Repository: JanDeDobbeleer/oh-my-posh
Pull request #535 (2021-03-16 10:36:45)

feat: template for time segment
### Prerequisites

- [x] I have read and understand the `CONTRIBUTING` guide
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes / features)
- [x] Docs have been added / updated (for bug fixes / features)

### Description

Template added for time segment

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/docs/docs/segment-time.md b/docs/docs/segment-time.md
index d482a2ad..8e060927 100644
--- a/docs/docs/segment-time.md
+++ b/docs/docs/segment-time.md
@@ -26,3 +26,12 @@ Show the current timestamp.
 - time_format: `string` - format to use, follows the [golang standard][format] - defaults to `15:04:05`
 
 [format]: https://gobyexample.com/time-formatting-parsing
+
+- template: `string` - A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the
+properties below. Only used when a value is set, making the above properties obsolete.
+
+  example: `{{ now | date \"January 02, 2006 15:04:05 PM\" | lower }}`
+
+## Template Properties
+
+- `.CurrentDate`: `time` - The time to display(testing purpose)
diff --git a/src/segment_time.go b/src/segment_time.go
index ac68844a..2851ec2d 100644
--- a/src/segment_time.go
+++ b/src/segment_time.go
@@ -1,12 +1,12 @@
 package main
 
-import (
-	"time"
-)
+import "time"
 
 type tempus struct {
-	props *properties
-	env   environmentInfo
+	props        *properties
+	env          environmentInfo
+	templateText string
+	CurrentDate  time.Time
 }
 
 const (
@@ -15,15 +15,36 @@ const (
 )
 
 func (t *tempus) enabled() bool {
+	// if no date set, use now(unit testing)
+	if t.CurrentDate.IsZero() {
+		t.CurrentDate = time.Now()
+	}
+	segmentTemplate := t.props.getString(SegmentTemplate, "")
+	if segmentTemplate != "" {
+		template := &textTemplate{
+			Template: segmentTemplate,
+			Context:  t,
+		}
+		t.templateText = template.render()
+		return len(t.templateText) > 0
+	}
 	return true
 }
 
 func (t *tempus) string() string {
-	timeFormatProperty := t.props.getString(TimeFormat, "15:04:05")
-	return time.Now().Format(timeFormatProperty)
+	return t.getFormattedText()
 }
 
 func (t *tempus) init(props *properties, env environmentInfo) {
 	t.props = props
 	t.env = env
 }
+
+func (t *tempus) getFormattedText() string {
+	if len(t.templateText) > 0 {
+		return t.templateText
+	}
+	// keep old behaviour if no template
+	timeFormatProperty := t.props.getString(TimeFormat, "15:04:05")
+	return t.CurrentDate.Format(timeFormatProperty)
+}
diff --git a/themes/schema.json b/themes/schema.json
index bde3f51c..fdc1c051 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -1282,6 +1282,9 @@
                     "title": "Time Format",
                     "description": "Format to use, follows the golang standard: https://gobyexample.com/time-formatting-parsing",
                     "default": "15:04:05"
+                  },
+                  "template": {
+                    "$ref": "#/definitions/template"
                   }
                 }
               }


Test patch:
diff --git a/src/segment_time_test.go b/src/segment_time_test.go
new file mode 100644
index 00000000..02fe8cd1
--- /dev/null
+++ b/src/segment_time_test.go
@@ -0,0 +1,57 @@
+package main
+
+import (
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestTimeSegmentTemplate(t *testing.T) {
+	// set date for unit test
+	currentDate := time.Now()
+	cases := []struct {
+		Case            string
+		ExpectedEnabled bool
+		ExpectedString  string
+		Template        string
+	}{
+		{
+			Case:            "no template",
+			Template:        "",
+			ExpectedString:  currentDate.Format("15:04:05"),
+			ExpectedEnabled: true,
+		},
+		{
+			Case:            "time only",
+			Template:        "{{.CurrentDate | date \"15:04:05\"}}",
+			ExpectedString:  currentDate.Format("15:04:05"),
+			ExpectedEnabled: true,
+		},
+		{
+			Case:            "lowercase",
+			Template:        "{{.CurrentDate | date \"January 02, 2006 15:04:05\" | lower }}",
+			ExpectedString:  strings.ToLower(currentDate.Format("January 02, 2006 15:04:05")),
+			ExpectedEnabled: true,
+		},
+	}
+
+	for _, tc := range cases {
+		env := new(MockedEnvironment)
+		props := &properties{
+			values: map[Property]interface{}{
+				SegmentTemplate: tc.Template,
+			},
+		}
+		tempus := &tempus{
+			env:         env,
+			props:       props,
+			CurrentDate: currentDate,
+		}
+		assert.Equal(t, tc.ExpectedEnabled, tempus.enabled())
+		if tc.ExpectedEnabled {
+			assert.Equal(t, tc.ExpectedString, tempus.string(), tc.Case)
+		}
+	}
+}