From ce7b7f1501befb6a1c3efcefbbfa949126879c34 Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Mon, 2 Jan 2023 16:33:25 +0100 Subject: [PATCH] fix(fish): different hyperlink format on linux --- src/cli/config_export_image.go | 2 +- src/cli/debug.go | 2 +- src/color/ansi.go | 13 ++++++++++--- src/color/ansi_test.go | 10 +++++----- src/color/text_test.go | 2 +- src/color/writer_test.go | 2 +- src/console/title_test.go | 4 ++-- src/engine/block.go | 2 +- src/engine/engine.go | 12 ++++++------ src/engine/engine_test.go | 6 +++--- src/engine/image_test.go | 2 +- src/engine/new.go | 4 ++-- 12 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/cli/config_export_image.go b/src/cli/config_export_image.go index 71c966a9..18de8ff0 100644 --- a/src/cli/config_export_image.go +++ b/src/cli/config_export_image.go @@ -59,7 +59,7 @@ Exports the config to an image file using customized output options.`, defer env.Close() cfg := engine.LoadConfig(env) ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain("") writerColors := cfg.MakeColors() writer := &color.AnsiWriter{ Ansi: ansi, diff --git a/src/cli/debug.go b/src/cli/debug.go index 4493e1c0..d898eaec 100644 --- a/src/cli/debug.go +++ b/src/cli/debug.go @@ -34,7 +34,7 @@ var debugCmd = &cobra.Command{ defer env.Close() cfg := engine.LoadConfig(env) ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain(env.GOOS()) writerColors := cfg.MakeColors() writer := &color.AnsiWriter{ Ansi: ansi, diff --git a/src/color/ansi.go b/src/color/ansi.go index 772e77f5..9e28f2e7 100644 --- a/src/color/ansi.go +++ b/src/color/ansi.go @@ -48,7 +48,7 @@ type Ansi struct { format string } -func (a *Ansi) Init(shellName string) { +func (a *Ansi) Init(shellName, goos string) { a.shell = shellName switch shellName { case shell.ZSH: @@ -139,10 +139,17 @@ func (a *Ansi) Init(shellName string) { a.dimmed = "\x1b[2m%s\x1b[22m" a.strikethrough = "\x1b[9m%s\x1b[29m" } + // see https://github.com/JanDeDobbeleer/oh-my-posh/issues/3287 + // when in fish on Linux, it seems hyperlinks ending with \\ prints a \ + // unlike on macOS + if shellName == shell.FISH && goos == "linux" { + a.hyperlink = "\x1b]8;;%s\x1b%s\x1b]8;;\x1b\\" + a.hyperlinkRegex = "(?P\x1b]8;;(.+)\x1b?(?P.+)\x1b]8;;\x1b\\\\)" + } } -func (a *Ansi) InitPlain() { - a.Init(shell.PLAIN) +func (a *Ansi) InitPlain(goos string) { + a.Init(shell.PLAIN, goos) } func (a *Ansi) GenerateHyperlink(text string) string { diff --git a/src/color/ansi_test.go b/src/color/ansi_test.go index ff56fd73..0c80f316 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) + a.Init(tc.ShellName, "") hyperlinkText := a.GenerateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } @@ -53,7 +53,7 @@ func TestGenerateHyperlinkWithUrl(t *testing.T) { } for _, tc := range cases { a := Ansi{} - a.Init(tc.ShellName) + a.Init(tc.ShellName, "") hyperlinkText := a.GenerateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } @@ -71,7 +71,7 @@ func TestGenerateHyperlinkWithUrlNoName(t *testing.T) { } for _, tc := range cases { a := Ansi{} - a.Init(tc.ShellName) + a.Init(tc.ShellName, "") hyperlinkText := a.GenerateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } @@ -96,7 +96,7 @@ func TestFormatText(t *testing.T) { } for _, tc := range cases { a := Ansi{} - a.InitPlain() + a.InitPlain("") formattedText := a.formatText(tc.Text) assert.Equal(t, tc.Expected, formattedText, tc.Case) } @@ -115,7 +115,7 @@ func TestGenerateFileLink(t *testing.T) { } for _, tc := range cases { a := Ansi{} - a.Init(shell.PWSH) + a.Init(shell.PWSH, "") 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 index e192a693..ff329a9c 100644 --- a/src/color/text_test.go +++ b/src/color/text_test.go @@ -37,7 +37,7 @@ func TestMeasureText(t *testing.T) { for _, shell := range shells { for _, tc := range cases { ansi := &Ansi{} - ansi.Init(shell) + ansi.Init(shell, "") tmpl := &template.Text{ Template: tc.Template, Env: env, diff --git a/src/color/writer_test.go b/src/color/writer_test.go index 4b92bbcb..2aeb9fe1 100644 --- a/src/color/writer_test.go +++ b/src/color/writer_test.go @@ -174,7 +174,7 @@ func TestWriteANSIColors(t *testing.T) { for _, tc := range cases { ansi := &Ansi{} - ansi.Init(shell.PWSH) + ansi.Init(shell.PWSH, "") renderer := &AnsiWriter{ Ansi: ansi, ParentColors: []*Color{tc.Parent}, diff --git a/src/console/title_test.go b/src/console/title_test.go index 4f8c4954..7742d950 100644 --- a/src/console/title_test.go +++ b/src/console/title_test.go @@ -62,7 +62,7 @@ func TestGetTitle(t *testing.T) { Folder: "vagrant", }) ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain("") ct := &Title{ Env: env, Ansi: ansi, @@ -117,7 +117,7 @@ func TestGetConsoleTitleIfGethostnameReturnsError(t *testing.T) { HostName: "", }) ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain("") ct := &Title{ Env: env, Ansi: ansi, diff --git a/src/engine/block.go b/src/engine/block.go index 2d73a180..f2c51562 100644 --- a/src/engine/block.go +++ b/src/engine/block.go @@ -67,7 +67,7 @@ func (b *Block) Init(env platform.Environment, writer color.Writer, ansi *color. func (b *Block) InitPlain(env platform.Environment, config *Config) { b.ansi = &color.Ansi{} - b.ansi.InitPlain() + b.ansi.InitPlain(b.env.GOOS()) b.writer = &color.AnsiWriter{ Ansi: b.ansi, TerminalBackground: shell.ConsoleBackgroundColor(env, config.TerminalBackground), diff --git a/src/engine/engine.go b/src/engine/engine.go index a1419806..6fb640e1 100644 --- a/src/engine/engine.go +++ b/src/engine/engine.go @@ -43,7 +43,7 @@ func (e *Engine) string() string { return text } -func (e *Engine) canWriteRPrompt(rprompt bool) bool { +func (e *Engine) canWriteRightBlock(rprompt bool) bool { if rprompt && (e.rprompt == "" || e.Plain) { return false } @@ -188,7 +188,7 @@ func (e *Engine) renderBlock(block *Block) { text, length := block.RenderSegments() e.rpromptLength = length - if !e.canWriteRPrompt(false) { + if !e.canWriteRightBlock(false) { switch block.Overflow { case Break: e.newline() @@ -211,7 +211,7 @@ func (e *Engine) renderBlock(block *Block) { ansi := e.Ansi if e.Env.Shell() == shell.BASH { ansi = &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain(e.Env.GOOS()) } prompt := ansi.CarriageForward() prompt += ansi.GetCursorForRightWrite(length, block.HorizontalOffset) @@ -292,7 +292,7 @@ func (e *Engine) print() string { prompt += fmt.Sprintf("\nRPROMPT=\"%s\"", e.rprompt) return prompt case shell.PWSH, shell.PWSH5, shell.PLAIN, shell.NU: - if !e.canWriteRPrompt(true) { + if !e.canWriteRightBlock(true) { break } e.write(e.Ansi.SaveCursorPosition()) @@ -301,13 +301,13 @@ func (e *Engine) print() string { e.write(e.rprompt) e.write(e.Ansi.RestoreCursorPosition()) case shell.BASH: - if !e.canWriteRPrompt(true) { + if !e.canWriteRightBlock(true) { break } // in bash, the entire rprompt needs to be escaped for the prompt to be interpreted correctly // see https://github.com/jandedobbeleer/oh-my-posh/pull/2398 ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain(e.Env.GOOS()) prompt := ansi.SaveCursorPosition() prompt += ansi.CarriageForward() prompt += ansi.GetCursorForRightWrite(e.rpromptLength, 0) diff --git a/src/engine/engine_test.go b/src/engine/engine_test.go index 206d4cd7..0a7456e5 100644 --- a/src/engine/engine_test.go +++ b/src/engine/engine_test.go @@ -40,7 +40,7 @@ func TestCanWriteRPrompt(t *testing.T) { currentLineLength: tc.PromptLength, rprompt: "hello", } - got := engine.canWriteRPrompt(true) + got := engine.canWriteRightBlock(true) assert.Equal(t, tc.Expected, got, tc.Case) } } @@ -72,7 +72,7 @@ func TestPrintPWD(t *testing.T) { Shell: "shell", }) ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain("") engine := &Engine{ Env: env, Config: &Config{ @@ -102,7 +102,7 @@ func engineRender() { defer testClearDefaultConfig() ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain("") writerColors := cfg.MakeColors() writer := &color.AnsiWriter{ Ansi: ansi, diff --git a/src/engine/image_test.go b/src/engine/image_test.go index 3e7dcf73..b740537f 100644 --- a/src/engine/image_test.go +++ b/src/engine/image_test.go @@ -33,7 +33,7 @@ func runImageTest(config, content string) (string, error) { } defer os.Remove(file.Name()) ansi := &color.Ansi{} - ansi.InitPlain() + ansi.InitPlain("") image := &ImageRenderer{ AnsiString: content, Ansi: ansi, diff --git a/src/engine/new.go b/src/engine/new.go index 4769611f..ccb5b7f8 100644 --- a/src/engine/new.go +++ b/src/engine/new.go @@ -18,11 +18,11 @@ func New(flags *platform.Flags) *Engine { env.Init() cfg := LoadConfig(env) ansi := &color.Ansi{} - ansi.Init(env.Shell()) + ansi.Init(env.Shell(), env.GOOS()) var writer color.Writer if flags.Plain { - ansi.InitPlain() + ansi.InitPlain(env.GOOS()) writer = &color.PlainWriter{ Ansi: ansi, }