Repository: JanDeDobbeleer/oh-my-posh
Pull request #2301 (2022-05-20 19:55:37)

feat: support overline
### Prerequisites

- [x] I have read and understood the [contributing guide][CONTRIBUTING.md]
- [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

<!--TemplateBody-->

<!---

Tips:

If you're not comfortable with working with Git, we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[CONTRIBUTING.md]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/CONTRIBUTING.md
[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/color/ansi.go b/src/color/ansi.go
index e5bf1412..63862e2b 100644
--- a/src/color/ansi.go
+++ b/src/color/ansi.go
@@ -33,6 +33,7 @@ type Ansi struct {
 	bold                  string
 	italic                string
 	underline             string
+	overline              string
 	strikethrough         string
 	blink                 string
 	reverse               string
@@ -65,6 +66,7 @@ func (a *Ansi) Init(shellName string) {
 		a.bold = "%%{\x1b[1m%%}%s%%{\x1b[22m%%}"
 		a.italic = "%%{\x1b[3m%%}%s%%{\x1b[23m%%}"
 		a.underline = "%%{\x1b[4m%%}%s%%{\x1b[24m%%}"
+		a.overline = "%%{\x1b[53m%%}%s%%{\x1b[55m%%}"
 		a.blink = "%%{\x1b[5m%%}%s%%{\x1b[25m%%}"
 		a.reverse = "%%{\x1b[7m%%}%s%%{\x1b[27m%%}"
 		a.dimmed = "%%{\x1b[2m%%}%s%%{\x1b[22m%%}"
@@ -91,6 +93,7 @@ func (a *Ansi) Init(shellName string) {
 		a.bold = "\\[\x1b[1m\\]%s\\[\x1b[22m\\]"
 		a.italic = "\\[\x1b[3m\\]%s\\[\x1b[23m\\]"
 		a.underline = "\\[\x1b[4m\\]%s\\[\x1b[24m\\]"
+		a.overline = "\\[\x1b[53m\\]%s\\[\x1b[55m\\]"
 		a.blink = "\\[\x1b[5m\\]%s\\[\x1b[25m\\]"
 		a.reverse = "\\[\x1b[7m\\]%s\\[\x1b[27m\\]"
 		a.dimmed = "\\[\x1b[2m\\]%s\\[\x1b[22m\\]"
@@ -117,6 +120,7 @@ func (a *Ansi) Init(shellName string) {
 		a.bold = "\x1b[1m%s\x1b[22m"
 		a.italic = "\x1b[3m%s\x1b[23m"
 		a.underline = "\x1b[4m%s\x1b[24m"
+		a.overline = "\x1b[53m%s\x1b[55m"
 		a.blink = "\x1b[5m%s\x1b[25m"
 		a.reverse = "\x1b[7m%s\x1b[27m"
 		a.dimmed = "\x1b[2m%s\x1b[22m"
@@ -195,6 +199,8 @@ func (a *Ansi) formatText(text string) string {
 				formatted = fmt.Sprintf(a.bold, result["text"])
 			case "u":
 				formatted = fmt.Sprintf(a.underline, result["text"])
+			case "o":
+				formatted = fmt.Sprintf(a.overline, result["text"])
 			case "i":
 				formatted = fmt.Sprintf(a.italic, result["text"])
 			case "s":
@@ -209,7 +215,7 @@ func (a *Ansi) formatText(text string) string {
 			text = strings.Replace(text, result["context"], formatted, 1)
 		}
 	}
-	rgx := "(?P<context><(?P<format>[buisrdf])>(?P<text>[^<]+)</[buisrdf]>)"
+	rgx := "(?P<context><(?P<format>[buisrdfo])>(?P<text>[^<]+)</[buisrdfo]>)"
 	for results := regex.FindAllNamedRegexMatch(rgx, text); len(results) != 0; results = regex.FindAllNamedRegexMatch(rgx, text) {
 		replaceFormats(results)
 	}
diff --git a/website/docs/configuration/templates.md b/website/docs/configuration/templates.md
index d495e3b3..8a86fba9 100644
--- a/website/docs/configuration/templates.md
+++ b/website/docs/configuration/templates.md
@@ -94,6 +94,7 @@ You can make use of the following syntax to decorate text:
 
 - `<b>bold</b>`: renders `bold` as bold text
 - `<u>underline</u>`: renders `underline` as underlined text
+- `<o>overline</o>`: renders `overline` as overlined text
 - `<i>italic</i>`: renders `italic` as italic text
 - `
strikethrough
`: renders `strikethrough` as strikethrough text
 - `<d>dimmed</d>`: renders `dimmed` as dimmed text


Test patch:
diff --git a/src/color/ansi_test.go b/src/color/ansi_test.go
index 1b5b0e4f..a1a36466 100644
--- a/src/color/ansi_test.go
+++ b/src/color/ansi_test.go
@@ -76,6 +76,7 @@ func TestFormatText(t *testing.T) {
 		{Case: "flash", Text: "This <f>is</f> white", Expected: "This \x1b[5mis\x1b[25m white"},
 		{Case: "reversed", Text: "This <r>is</r> white", Expected: "This \x1b[7mis\x1b[27m white"},
 		{Case: "double", Text: "This <i><f>is</f></i> white", Expected: "This \x1b[3m\x1b[5mis\x1b[25m\x1b[23m white"},
+		{Case: "overline", Text: "This <o>is</o> white", Expected: "This \x1b[53mis\x1b[55m white"},
 	}
 	for _, tc := range cases {
 		a := Ansi{}