refactor(segment): cleaner logic

This commit is contained in:
Jan De Dobbeleer 2022-02-02 12:16:39 +01:00 committed by Jan De Dobbeleer
parent 55ab413d6e
commit a5162b0f19
3 changed files with 47 additions and 65 deletions

View file

@ -80,14 +80,14 @@ func (b *Block) enabled() bool {
return false
}
func (b *Block) setStringValues() {
func (b *Block) renderSegmentsText() {
wg := sync.WaitGroup{}
wg.Add(len(b.Segments))
defer wg.Wait()
for _, segment := range b.Segments {
go func(s *Segment) {
defer wg.Done()
s.setStringValue(b.env)
s.renderText(b.env)
}(segment)
}
}
@ -110,10 +110,10 @@ func (b *Block) renderSegment(segment *Segment) {
b.writePowerline(false)
switch b.activeSegment.Style {
case Plain, Powerline:
b.writer.Write(b.activeBackground, b.activeForeground, segment.stringValue)
b.writer.Write(b.activeBackground, b.activeForeground, segment.text)
case Diamond:
b.writer.Write(color.Transparent, b.activeBackground, b.activeSegment.LeadingDiamond)
b.writer.Write(b.activeBackground, b.activeForeground, segment.stringValue)
b.writer.Write(b.activeBackground, b.activeForeground, segment.text)
b.writer.Write(color.Transparent, b.activeBackground, b.activeSegment.TrailingDiamond)
}
b.previousActiveSegment = b.activeSegment
@ -168,30 +168,22 @@ func (b *Block) debug() (int, []*SegmentTiming) {
var segmentTimings []*SegmentTiming
largestSegmentNameLength := 0
for _, segment := range b.Segments {
err := segment.mapSegmentWithWriter(b.env)
if err != nil || !segment.shouldIncludeFolder() {
continue
}
var segmentTiming SegmentTiming
segmentTiming.name = string(segment.Type)
segmentTiming.nameLength = len(segmentTiming.name)
if segmentTiming.nameLength > largestSegmentNameLength {
largestSegmentNameLength = segmentTiming.nameLength
}
// enabled() timing
start := time.Now()
segmentTiming.enabled = segment.enabled()
segmentTiming.enabledDuration = time.Since(start)
// string() timing
if segmentTiming.enabled {
start = time.Now()
segment.stringValue = segment.string()
segmentTiming.stringDuration = time.Since(start)
segment.renderText(b.env)
segmentTiming.active = segment.active
segmentTiming.text = segment.text
if segmentTiming.active {
b.renderSegment(segment)
b.writePowerline(true)
segmentTiming.stringValue = b.writer.String()
segmentTiming.text = b.writer.String()
b.writer.Reset()
}
segmentTiming.duration = time.Since(start)
segmentTimings = append(segmentTimings, &segmentTiming)
}
return largestSegmentNameLength, segmentTimings

View file

@ -83,7 +83,7 @@ func (e *Engine) renderBlock(block *Block) {
} else {
block.init(e.Env, e.Writer, e.Ansi)
}
block.setStringValues()
block.renderSegmentsText()
if !block.enabled() {
return
}
@ -136,12 +136,11 @@ func (e *Engine) Debug(version string) string {
consoleTitle := e.ConsoleTitle.GetTitle()
duration := time.Since(start)
segmentTiming := &SegmentTiming{
name: "ConsoleTitle",
nameLength: 12,
enabled: e.Config.ConsoleTitle,
stringValue: consoleTitle,
enabledDuration: 0,
stringDuration: duration,
name: "ConsoleTitle",
nameLength: 12,
active: e.Config.ConsoleTitle,
text: consoleTitle,
duration: duration,
}
segmentTimings = append(segmentTimings, segmentTiming)
// loop each segments of each blocks
@ -157,12 +156,9 @@ func (e *Engine) Debug(version string) string {
// pad the output so the tabs render correctly
largestSegmentNameLength += 7
for _, segment := range segmentTimings {
duration := segment.enabledDuration.Milliseconds()
if segment.enabled {
duration += segment.stringDuration.Milliseconds()
}
segmentName := fmt.Sprintf("%s(%t)", segment.name, segment.enabled)
e.write(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.stringValue))
duration := segment.duration.Milliseconds()
segmentName := fmt.Sprintf("%s(%t)", segment.name, segment.active)
e.write(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.text))
}
e.write(fmt.Sprintf("\n\x1b[1mRun duration:\x1b[0m %s\n", time.Since(start)))
e.write(fmt.Sprintf("\n\x1b[1mCache path:\x1b[0m %s\n", e.Env.CachePath()))
@ -209,10 +205,10 @@ func (e *Engine) RenderTooltip(tip string) string {
if err := tooltip.mapSegmentWithWriter(e.Env); err != nil {
return ""
}
if !tooltip.enabled() {
if !tooltip.writer.Enabled() {
return ""
}
tooltip.stringValue = tooltip.string()
tooltip.text = tooltip.string()
// little hack to reuse the current logic
block := &Block{
Alignment: Right,
@ -278,7 +274,7 @@ func (e *Engine) RenderRPrompt() string {
return ""
}
block.init(e.Env, e.Writer, e.Ansi)
block.setStringValues()
block.renderSegmentsText()
if !block.enabled() {
return ""
}

View file

@ -27,19 +27,18 @@ type Segment struct {
TrailingDiamond string `json:"trailing_diamond,omitempty"`
Properties properties.Map `json:"properties,omitempty"`
writer SegmentWriter
stringValue string
text string
active bool
env environment.Environment
}
// SegmentTiming holds the timing context for a segment
type SegmentTiming struct {
name string
nameLength int
enabled bool
stringValue string
enabledDuration time.Duration
stringDuration time.Duration
name string
nameLength int
active bool
text string
duration time.Duration
}
// SegmentWriter is the interface used to define what and if to write to the prompt
@ -150,26 +149,6 @@ const (
IPIFY SegmentType = "ipify"
)
func (segment *Segment) string() string {
segmentTemplate := segment.Properties.GetString(properties.SegmentTemplate, segment.writer.Template())
tmpl := &template.Text{
Template: segmentTemplate,
Context: segment.writer,
Env: segment.env,
}
text, err := tmpl.Render()
if err != nil {
return err.Error()
}
segment.active = len(strings.TrimSpace(text)) > 0
return text
}
func (segment *Segment) enabled() bool {
segment.active = segment.writer.Enabled()
return segment.active
}
func (segment *Segment) shouldIncludeFolder() bool {
cwdIncluded := segment.cwdIncluded()
cwdExcluded := segment.cwdExcluded()
@ -296,7 +275,21 @@ func (segment *Segment) mapSegmentWithWriter(env environment.Environment) error
return errors.New("unable to map writer")
}
func (segment *Segment) setStringValue(env environment.Environment) {
func (segment *Segment) string() string {
segmentTemplate := segment.Properties.GetString(properties.SegmentTemplate, segment.writer.Template())
tmpl := &template.Text{
Template: segmentTemplate,
Context: segment.writer,
Env: segment.env,
}
text, err := tmpl.Render()
if err != nil {
return err.Error()
}
return text
}
func (segment *Segment) renderText(env environment.Environment) {
defer func() {
err := recover()
if err == nil {
@ -305,14 +298,15 @@ func (segment *Segment) setStringValue(env environment.Environment) {
// display a message explaining omp failed(with the err)
message := fmt.Sprintf("\noh-my-posh fatal error rendering %s segment:%s\n\n%s\n", segment.Type, err, debug.Stack())
fmt.Println(message)
segment.stringValue = "error"
segment.text = "error"
segment.active = true
}()
err := segment.mapSegmentWithWriter(env)
if err != nil || !segment.shouldIncludeFolder() {
return
}
if segment.enabled() {
segment.stringValue = segment.string()
if segment.writer.Enabled() {
segment.text = segment.string()
segment.active = len(strings.TrimSpace(segment.text)) > 0
}
}