From 375184cf0e8ec0529de21e949fbea43b3c7823a6 Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Sat, 13 Feb 2021 16:27:31 +0100 Subject: [PATCH] feat: allow color templates relates to #397 --- src/engine.go | 24 +++++++-------- src/segment.go | 62 ++++++++++++++++++++++++++++++-------- src/segment_test.go | 73 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 27 deletions(-) diff --git a/src/engine.go b/src/engine.go index 35a68cb4..10418ced 100644 --- a/src/engine.go +++ b/src/engine.go @@ -38,7 +38,7 @@ func (e *engine) getPowerlineColor(foreground bool) string { if foreground && e.previousActiveSegment.Style != Powerline { return Transparent } - return e.previousActiveSegment.Background + return e.previousActiveSegment.background() } func (e *engine) writePowerLineSeparator(background, foreground string, end bool) { @@ -58,12 +58,12 @@ func (e *engine) endPowerline() { e.activeSegment.Style != Powerline && e.previousActiveSegment != nil && e.previousActiveSegment.Style == Powerline { - e.writePowerLineSeparator(e.getPowerlineColor(false), e.previousActiveSegment.Background, true) + e.writePowerLineSeparator(e.getPowerlineColor(false), e.previousActiveSegment.background(), true) } } func (e *engine) renderPowerLineSegment(text string) { - e.writePowerLineSeparator(e.activeSegment.Background, e.getPowerlineColor(true), false) + e.writePowerLineSeparator(e.activeSegment.background(), e.getPowerlineColor(true), false) e.renderText(text) } @@ -72,22 +72,22 @@ func (e *engine) renderPlainSegment(text string) { } func (e *engine) renderDiamondSegment(text string) { - e.color.write(Transparent, e.activeSegment.Background, e.activeSegment.LeadingDiamond) + e.color.write(Transparent, e.activeSegment.background(), e.activeSegment.LeadingDiamond) e.renderText(text) - e.color.write(Transparent, e.activeSegment.Background, e.activeSegment.TrailingDiamond) + e.color.write(Transparent, e.activeSegment.background(), e.activeSegment.TrailingDiamond) } func (e *engine) renderText(text string) { defaultValue := " " - if e.activeSegment.Background != "" { - defaultValue = fmt.Sprintf("<%s>\u2588", e.activeSegment.Background) + if e.activeSegment.background() != "" { + defaultValue = fmt.Sprintf("<%s>\u2588", e.activeSegment.background()) } text = e.color.formats.generateHyperlink(text) prefix := e.activeSegment.getValue(Prefix, defaultValue) postfix := e.activeSegment.getValue(Postfix, defaultValue) - e.color.write(e.activeSegment.Background, e.activeSegment.Foreground, fmt.Sprintf("%s%s%s", prefix, text, postfix)) + e.color.write(e.activeSegment.background(), e.activeSegment.foreground(), fmt.Sprintf("%s%s%s", prefix, text, postfix)) } func (e *engine) renderSegmentText(text string) { @@ -112,12 +112,10 @@ func (e *engine) renderBlockSegments(block *Block) string { } e.activeSegment = segment e.endPowerline() - e.activeSegment.Background = segment.props.background - e.activeSegment.Foreground = segment.props.foreground e.renderSegmentText(segment.stringValue) } if e.previousActiveSegment != nil && e.previousActiveSegment.Style == Powerline { - e.writePowerLineSeparator(Transparent, e.previousActiveSegment.Background, true) + e.writePowerLineSeparator(Transparent, e.previousActiveSegment.background(), true) } return e.color.string() } @@ -211,11 +209,9 @@ func (e *engine) debug() { segmentTiming.stringDuration = time.Since(start) e.previousActiveSegment = nil e.activeSegment = segment - e.activeSegment.Background = segment.props.background - e.activeSegment.Foreground = segment.props.foreground e.renderSegmentText(segmentTiming.stringValue) if e.activeSegment.Style == Powerline { - e.writePowerLineSeparator(Transparent, e.activeSegment.Background, true) + e.writePowerLineSeparator(Transparent, e.activeSegment.background(), true) } segmentTiming.stringValue = e.color.string() e.color.builder.Reset() diff --git a/src/segment.go b/src/segment.go index 881593d0..dc02d87e 100644 --- a/src/segment.go +++ b/src/segment.go @@ -7,19 +7,21 @@ import ( // Segment represent a single segment and it's configuration type Segment struct { - Type SegmentType `json:"type"` - Style SegmentStyle `json:"style"` - PowerlineSymbol string `json:"powerline_symbol"` - InvertPowerline bool `json:"invert_powerline"` - Foreground string `json:"foreground"` - Background string `json:"background"` - LeadingDiamond string `json:"leading_diamond"` - TrailingDiamond string `json:"trailing_diamond"` - Properties map[Property]interface{} `json:"properties"` - props *properties - writer SegmentWriter - stringValue string - active bool + Type SegmentType `json:"type"` + Style SegmentStyle `json:"style"` + PowerlineSymbol string `json:"powerline_symbol"` + InvertPowerline bool `json:"invert_powerline"` + Foreground string `json:"foreground"` + ForegroundTemplates []string `json:"foreground_templates"` + Background string `json:"background"` + BackgroundTemplates []string `json:"background_templates"` + LeadingDiamond string `json:"leading_diamond"` + TrailingDiamond string `json:"trailing_diamond"` + Properties map[Property]interface{} `json:"properties"` + props *properties + writer SegmentWriter + stringValue string + active bool } // SegmentWriter is the interface used to define what and if to write to the prompt @@ -123,6 +125,40 @@ func (segment *Segment) shouldIgnoreFolder(cwd string) bool { return false } +func (segment *Segment) getColor(templates []string, defaultColor string) string { + if len(templates) == 0 { + return defaultColor + } + txtTemplate := &textTemplate{ + Context: segment.writer, + } + for _, template := range templates { + txtTemplate.Template = template + value := txtTemplate.render() + if value == "" { + continue + } + return value + } + return defaultColor +} + +func (segment *Segment) foreground() string { + color := segment.Foreground + if segment.props != nil { + color = segment.props.foreground + } + return segment.getColor(segment.ForegroundTemplates, color) +} + +func (segment *Segment) background() string { + color := segment.Background + if segment.props != nil { + color = segment.props.background + } + return segment.getColor(segment.BackgroundTemplates, color) +} + func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error { functions := map[SegmentType]SegmentWriter{ Session: &session{}, diff --git a/src/segment_test.go b/src/segment_test.go index 07e4e10b..10fdb2db 100644 --- a/src/segment_test.go +++ b/src/segment_test.go @@ -109,3 +109,76 @@ func TestShouldIgnoreFolderRegexInvertedNonEscaped(t *testing.T) { }() segment.shouldIgnoreFolder(cwd) } + +func TestGetColors(t *testing.T) { + cases := []struct { + Case string + Background bool + ExpectedString string + Templates []string + DefaultColor string + Region string + Profile string + }{ + {Case: "No template - foreground", ExpectedString: "color", Background: false, DefaultColor: "color"}, + {Case: "No template - background", ExpectedString: "color", Background: true, DefaultColor: "color"}, + {Case: "Nil template", ExpectedString: "color", DefaultColor: "color", Templates: nil}, + { + Case: "Template - default", + ExpectedString: "color", + DefaultColor: "color", + Templates: []string{ + "{{if contains \"john\" .Profile}}color2{{end}}", + }, + Profile: "doe", + }, + { + Case: "Template - override", + ExpectedString: "color2", + DefaultColor: "color", + Templates: []string{ + "{{if contains \"john\" .Profile}}color2{{end}}", + }, + Profile: "john", + }, + { + Case: "Template - override multiple", + ExpectedString: "color3", + DefaultColor: "color", + Templates: []string{ + "{{if contains \"doe\" .Profile}}color2{{end}}", + "{{if contains \"john\" .Profile}}color3{{end}}", + }, + Profile: "john", + }, + { + Case: "Template - override multiple no match", + ExpectedString: "color", + DefaultColor: "color", + Templates: []string{ + "{{if contains \"doe\" .Profile}}color2{{end}}", + "{{if contains \"philip\" .Profile}}color3{{end}}", + }, + Profile: "john", + }, + } + for _, tc := range cases { + segment := &Segment{ + writer: &aws{ + Profile: tc.Profile, + Region: tc.Region, + }, + } + if tc.Background { + segment.Background = tc.DefaultColor + segment.BackgroundTemplates = tc.Templates + color := segment.background() + assert.Equal(t, tc.ExpectedString, color, tc.Case) + continue + } + segment.Foreground = tc.DefaultColor + segment.ForegroundTemplates = tc.Templates + color := segment.foreground() + assert.Equal(t, tc.ExpectedString, color, tc.Case) + } +}