mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-27 20:09:39 -08:00
fix(segment): evaluate all needs
This commit is contained in:
parent
472bd6fba7
commit
7de2809187
|
@ -3,12 +3,14 @@ package config
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/color"
|
"github.com/jandedobbeleer/oh-my-posh/src/color"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
"github.com/jandedobbeleer/oh-my-posh/src/properties"
|
||||||
|
"github.com/jandedobbeleer/oh-my-posh/src/regex"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/template"
|
"github.com/jandedobbeleer/oh-my-posh/src/template"
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ type Segment struct {
|
||||||
env runtime.Environment
|
env runtime.Environment
|
||||||
Properties properties.Map `json:"properties,omitempty" toml:"properties,omitempty"`
|
Properties properties.Map `json:"properties,omitempty" toml:"properties,omitempty"`
|
||||||
Cache *cache.Config `json:"cache,omitempty" toml:"cache,omitempty"`
|
Cache *cache.Config `json:"cache,omitempty" toml:"cache,omitempty"`
|
||||||
Style SegmentStyle `json:"style,omitempty" toml:"style,omitempty"`
|
Alias string `json:"alias,omitempty" toml:"alias,omitempty"`
|
||||||
styleCache SegmentStyle
|
styleCache SegmentStyle
|
||||||
name string
|
name string
|
||||||
LeadingDiamond string `json:"leading_diamond,omitempty" toml:"leading_diamond,omitempty"`
|
LeadingDiamond string `json:"leading_diamond,omitempty" toml:"leading_diamond,omitempty"`
|
||||||
|
@ -52,18 +54,19 @@ type Segment struct {
|
||||||
Background color.Ansi `json:"background,omitempty" toml:"background,omitempty"`
|
Background color.Ansi `json:"background,omitempty" toml:"background,omitempty"`
|
||||||
Filler string `json:"filler,omitempty" toml:"filler,omitempty"`
|
Filler string `json:"filler,omitempty" toml:"filler,omitempty"`
|
||||||
Type SegmentType `json:"type,omitempty" toml:"type,omitempty"`
|
Type SegmentType `json:"type,omitempty" toml:"type,omitempty"`
|
||||||
Alias string `json:"alias,omitempty" toml:"alias,omitempty"`
|
Style SegmentStyle `json:"style,omitempty" toml:"style,omitempty"`
|
||||||
LeadingPowerlineSymbol string `json:"leading_powerline_symbol,omitempty" toml:"leading_powerline_symbol,omitempty"`
|
LeadingPowerlineSymbol string `json:"leading_powerline_symbol,omitempty" toml:"leading_powerline_symbol,omitempty"`
|
||||||
ForegroundTemplates template.List `json:"foreground_templates,omitempty" toml:"foreground_templates,omitempty"`
|
|
||||||
Tips []string `json:"tips,omitempty" toml:"tips,omitempty"`
|
Tips []string `json:"tips,omitempty" toml:"tips,omitempty"`
|
||||||
|
ForegroundTemplates template.List `json:"foreground_templates,omitempty" toml:"foreground_templates,omitempty"`
|
||||||
BackgroundTemplates template.List `json:"background_templates,omitempty" toml:"background_templates,omitempty"`
|
BackgroundTemplates template.List `json:"background_templates,omitempty" toml:"background_templates,omitempty"`
|
||||||
Templates template.List `json:"templates,omitempty" toml:"templates,omitempty"`
|
Templates template.List `json:"templates,omitempty" toml:"templates,omitempty"`
|
||||||
ExcludeFolders []string `json:"exclude_folders,omitempty" toml:"exclude_folders,omitempty"`
|
ExcludeFolders []string `json:"exclude_folders,omitempty" toml:"exclude_folders,omitempty"`
|
||||||
IncludeFolders []string `json:"include_folders,omitempty" toml:"include_folders,omitempty"`
|
IncludeFolders []string `json:"include_folders,omitempty" toml:"include_folders,omitempty"`
|
||||||
Duration time.Duration `json:"-" toml:"-"`
|
Needs []string `json:"-" toml:"-"`
|
||||||
NameLength int `json:"-" toml:"-"`
|
NameLength int `json:"-" toml:"-"`
|
||||||
MaxWidth int `json:"max_width,omitempty" toml:"max_width,omitempty"`
|
MaxWidth int `json:"max_width,omitempty" toml:"max_width,omitempty"`
|
||||||
MinWidth int `json:"min_width,omitempty" toml:"min_width,omitempty"`
|
MinWidth int `json:"min_width,omitempty" toml:"min_width,omitempty"`
|
||||||
|
Duration time.Duration `json:"-" toml:"-"`
|
||||||
Interactive bool `json:"interactive,omitempty" toml:"interactive,omitempty"`
|
Interactive bool `json:"interactive,omitempty" toml:"interactive,omitempty"`
|
||||||
Enabled bool `json:"-" toml:"-"`
|
Enabled bool `json:"-" toml:"-"`
|
||||||
Newline bool `json:"newline,omitempty" toml:"newline,omitempty"`
|
Newline bool `json:"newline,omitempty" toml:"newline,omitempty"`
|
||||||
|
@ -95,6 +98,8 @@ func (segment *Segment) Execute(env runtime.Environment) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer segment.evaluateNeeds()
|
||||||
|
|
||||||
err := segment.MapSegmentWithWriter(env)
|
err := segment.MapSegmentWithWriter(env)
|
||||||
if err != nil || !segment.shouldIncludeFolder() {
|
if err != nil || !segment.shouldIncludeFolder() {
|
||||||
return
|
return
|
||||||
|
@ -311,3 +316,30 @@ func (segment *Segment) cwdIncluded() bool {
|
||||||
func (segment *Segment) cwdExcluded() bool {
|
func (segment *Segment) cwdExcluded() bool {
|
||||||
return segment.env.DirMatchesOneOf(segment.env.Pwd(), segment.ExcludeFolders)
|
return segment.env.DirMatchesOneOf(segment.env.Pwd(), segment.ExcludeFolders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (segment *Segment) evaluateNeeds() {
|
||||||
|
value := segment.Template
|
||||||
|
|
||||||
|
if len(segment.ForegroundTemplates) != 0 {
|
||||||
|
value += strings.Join(segment.ForegroundTemplates, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(segment.BackgroundTemplates) != 0 {
|
||||||
|
value += strings.Join(segment.BackgroundTemplates, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(value, ".Segments.") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := regex.FindAllNamedRegexMatch(`\.Segments\.(?P<NAME>[a-zA-Z0-9]+)`, value)
|
||||||
|
for _, name := range matches {
|
||||||
|
segmentName := name["NAME"]
|
||||||
|
|
||||||
|
if len(name) == 0 || slices.Contains(segment.Needs, segmentName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
segment.Needs = append(segment.Needs, segmentName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -160,3 +160,46 @@ func TestGetColors(t *testing.T) {
|
||||||
assert.Equal(t, tc.Expected, fgColor, tc.Case)
|
assert.Equal(t, tc.Expected, fgColor, tc.Case)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEvaluateNeeds(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Segment *Segment
|
||||||
|
Case string
|
||||||
|
Needs []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Case: "No needs",
|
||||||
|
Segment: &Segment{
|
||||||
|
Template: "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Template needs",
|
||||||
|
Segment: &Segment{
|
||||||
|
Template: "{{ .Segments.Git.URL }}",
|
||||||
|
},
|
||||||
|
Needs: []string{"Git"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Template & Foreground needs",
|
||||||
|
Segment: &Segment{
|
||||||
|
Template: "{{ .Segments.Git.URL }}",
|
||||||
|
ForegroundTemplates: []string{"foo", "{{ .Segments.Os.Icon }}"},
|
||||||
|
},
|
||||||
|
Needs: []string{"Git", "Os"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Template & Foreground & Background needs",
|
||||||
|
Segment: &Segment{
|
||||||
|
Template: "{{ .Segments.Git.URL }}",
|
||||||
|
ForegroundTemplates: []string{"foo", "{{ .Segments.Os.Icon }}"},
|
||||||
|
BackgroundTemplates: []string{"bar", "{{ .Segments.Exit.Icon }}"},
|
||||||
|
},
|
||||||
|
Needs: []string{"Git", "Os", "Exit"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range cases {
|
||||||
|
tc.Segment.evaluateNeeds()
|
||||||
|
assert.Equal(t, tc.Needs, tc.Segment.Needs, tc.Case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,8 @@ package prompt
|
||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/config"
|
"github.com/jandedobbeleer/oh-my-posh/src/config"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/regex"
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -113,12 +111,7 @@ func (e *Engine) writeSegment(index int, block *config.Block, segment *config.Se
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) canRenderSegment(segment *config.Segment, executed []string) bool {
|
func (e *Engine) canRenderSegment(segment *config.Segment, executed []string) bool {
|
||||||
if !strings.Contains(segment.Template, ".Segments.") {
|
for _, name := range segment.Needs {
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
matches := regex.FindNamedRegexMatch(`\.Segments\.(?P<NAME>[a-zA-Z0-9]+)`, segment.Template)
|
|
||||||
for _, name := range matches {
|
|
||||||
if slices.Contains(executed, name) {
|
if slices.Contains(executed, name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,37 +36,34 @@ func TestRenderBlock(t *testing.T) {
|
||||||
func TestCanRenderSegment(t *testing.T) {
|
func TestCanRenderSegment(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Case string
|
Case string
|
||||||
Template string
|
Executed []string
|
||||||
ExecutedSegments []string
|
Needs []string
|
||||||
Expected bool
|
Expected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Case: "No cross segment dependencies",
|
Case: "No cross segment dependencies",
|
||||||
Expected: true,
|
Expected: true,
|
||||||
Template: "Hello",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Case: "Cross segment dependencies, nothing executed",
|
Case: "Cross segment dependencies, nothing executed",
|
||||||
Expected: false,
|
Expected: false,
|
||||||
Template: "Hello {{ .Segments.Foo.World }} {{ .Segments.Foo.Bar }}",
|
Needs: []string{"Foo"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Case: "Cross segment dependencies, available",
|
Case: "Cross segment dependencies, available",
|
||||||
Expected: true,
|
Expected: true,
|
||||||
Template: "Hello {{ .Segments.Foo.World }}",
|
Executed: []string{"Foo"},
|
||||||
ExecutedSegments: []string{
|
Needs: []string{"Foo"},
|
||||||
"Foo",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
segment := &config.Segment{
|
segment := &config.Segment{
|
||||||
Type: "text",
|
Type: "text",
|
||||||
Template: c.Template,
|
Needs: c.Needs,
|
||||||
}
|
}
|
||||||
|
|
||||||
engine := &Engine{}
|
engine := &Engine{}
|
||||||
got := engine.canRenderSegment(segment, c.ExecutedSegments)
|
got := engine.canRenderSegment(segment, c.Executed)
|
||||||
|
|
||||||
assert.Equal(t, c.Expected, got, c.Case)
|
assert.Equal(t, c.Expected, got, c.Case)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue