diff --git a/src/color/ansi.go b/src/color/ansi.go index e5c6fbdf..29fb7a05 100644 --- a/src/color/ansi.go +++ b/src/color/ansi.go @@ -67,7 +67,7 @@ func (a *Ansi) Init(shellName string) { a.escapeLeft = "%{" a.escapeRight = "%}" a.hyperlink = "%%{\x1b]8;;%s\x1b\\\\%%}%s%%{\x1b]8;;\x1b\\\\%%}" - a.hyperlinkRegex = `(?P\x1b]8;;(.+)\x1b\\\\(?P.+)\x1b]8;;\x1b\\\\)` + a.hyperlinkRegex = `(?P%{\x1b]8;;(.+)\x1b\\\\%}(?P.+)%{\x1b]8;;\x1b\\\\%})` a.osc99 = "%%{\x1b]9;9;\"%s\"\x1b\\%%}" a.bold = "%%{\x1b[1m%%}%s%%{\x1b[22m%%}" a.italic = "%%{\x1b[3m%%}%s%%{\x1b[23m%%}" @@ -93,7 +93,7 @@ func (a *Ansi) Init(shellName string) { a.escapeLeft = "\\[" a.escapeRight = "\\]" a.hyperlink = "\\[\x1b]8;;%s\x1b\\\\\\]%s\\[\x1b]8;;\x1b\\\\\\]" - a.hyperlinkRegex = `(?P\x1b]8;;(.+)\x1b\\\\(?P.+)\x1b]8;;\x1b\\\\)` + a.hyperlinkRegex = `(?P\\\[\x1b\]8;;(.+)\x1b\\\\\\\](?P.+)\\\[\x1b\]8;;\x1b\\\\\\\])` a.osc99 = "\\[\x1b]9;9;\"%s\"\x1b\\\\\\]" a.bold = "\\[\x1b[1m\\]%s\\[\x1b[22m\\]" a.italic = "\\[\x1b[3m\\]%s\\[\x1b[23m\\]" @@ -119,7 +119,9 @@ func (a *Ansi) Init(shellName string) { a.escapeLeft = "" a.escapeRight = "" a.hyperlink = "\x1b]8;;%s\x1b\\%s\x1b]8;;\x1b\\" - a.hyperlinkRegex = `(?P\x1b]8;;(.+)\x1b\\(?P.+)\x1b]8;;\x1b\\)` + // a.hyperlinkRegex = "(?P\x1b]8;;(.+)\x1b\\(?P.+)\x1b]8;;\x1b\\)" + // \x1b]8;;https://ohmyposh.dev\x1b\\link\x1b]8;;\x1b\\ + a.hyperlinkRegex = "(?P\x1b]8;;(.+)\x1b\\\\\\\\?(?P.+)\x1b]8;;\x1b\\\\)" a.osc99 = "\x1b]9;9;\"%s\"\x1b\\" a.bold = "\x1b[1m%s\x1b[22m" a.italic = "\x1b[3m%s\x1b[23m" @@ -224,7 +226,7 @@ func (a *Ansi) initEscapeSequences(shellName string) { } } -func (a *Ansi) generateHyperlink(text string) string { +func (a *Ansi) GenerateHyperlink(text string) string { // hyperlink matching results := regex.FindNamedRegexMatch("(?P(?:\\[(?P.+)\\])(?:\\((?P.*)\\)))", text) if len(results) != 3 { diff --git a/src/color/ansi_test.go b/src/color/ansi_test.go index 9bc319da..92afad2e 100644 --- a/src/color/ansi_test.go +++ b/src/color/ansi_test.go @@ -20,7 +20,7 @@ func TestGenerateHyperlinkNoUrl(t *testing.T) { for _, tc := range cases { a := Ansi{} a.Init(tc.ShellName) - hyperlinkText := a.generateHyperlink(tc.Text) + hyperlinkText := a.GenerateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } } @@ -38,7 +38,7 @@ func TestGenerateHyperlinkWithUrl(t *testing.T) { for _, tc := range cases { a := Ansi{} a.Init(tc.ShellName) - hyperlinkText := a.generateHyperlink(tc.Text) + hyperlinkText := a.GenerateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } } @@ -56,7 +56,7 @@ func TestGenerateHyperlinkWithUrlNoName(t *testing.T) { for _, tc := range cases { a := Ansi{} a.Init(tc.ShellName) - hyperlinkText := a.generateHyperlink(tc.Text) + hyperlinkText := a.GenerateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } } diff --git a/src/color/text_test.go b/src/color/text_test.go new file mode 100644 index 00000000..92123779 --- /dev/null +++ b/src/color/text_test.go @@ -0,0 +1,50 @@ +package color + +import ( + "fmt" + "oh-my-posh/environment" + "oh-my-posh/mock" + "oh-my-posh/shell" + "oh-my-posh/template" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMeasureText(t *testing.T) { + cases := []struct { + Case string + Template string + Expected int + }{ + { + Case: "Simple text", + Template: "src", + Expected: 3, + }, + { + Case: "Hyperlink", + Template: `{{ url "link" "https://ohmyposh.dev" }}`, + Expected: 4, + }, + } + env := new(mock.MockedEnvironment) + env.On("TemplateCache").Return(&environment.TemplateCache{ + Env: make(map[string]string), + }) + shells := []string{shell.BASH, shell.ZSH, shell.PLAIN} + for _, shell := range shells { + for _, tc := range cases { + ansi := &Ansi{} + ansi.Init(shell) + tmpl := &template.Text{ + Template: tc.Template, + Env: env, + } + text, _ := tmpl.Render() + text = ansi.GenerateHyperlink(text) + got := ansi.MeasureText(text) + assert.Equal(t, tc.Expected, got, fmt.Sprintf("%s: %s", shell, tc.Case)) + } + } +} diff --git a/src/color/writer.go b/src/color/writer.go index 90556800..87809bd6 100644 --- a/src/color/writer.go +++ b/src/color/writer.go @@ -141,7 +141,7 @@ func (a *AnsiWriter) Write(background, foreground, text string) { bgAnsi, fgAnsi := a.asAnsiColors(background, foreground) text = a.Ansi.formatText(text) - text = a.Ansi.generateHyperlink(text) + text = a.Ansi.GenerateHyperlink(text) text = a.Ansi.EscapeText(text) // first we match for any potentially valid colors enclosed in <>