fix(fish): different hyperlink format on linux

This commit is contained in:
Jan De Dobbeleer 2023-01-02 16:33:25 +01:00 committed by Jan De Dobbeleer
parent 784b5f1492
commit ce7b7f1501
12 changed files with 34 additions and 27 deletions

View file

@ -59,7 +59,7 @@ Exports the config to an image file using customized output options.`,
defer env.Close() defer env.Close()
cfg := engine.LoadConfig(env) cfg := engine.LoadConfig(env)
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain("")
writerColors := cfg.MakeColors() writerColors := cfg.MakeColors()
writer := &color.AnsiWriter{ writer := &color.AnsiWriter{
Ansi: ansi, Ansi: ansi,

View file

@ -34,7 +34,7 @@ var debugCmd = &cobra.Command{
defer env.Close() defer env.Close()
cfg := engine.LoadConfig(env) cfg := engine.LoadConfig(env)
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain(env.GOOS())
writerColors := cfg.MakeColors() writerColors := cfg.MakeColors()
writer := &color.AnsiWriter{ writer := &color.AnsiWriter{
Ansi: ansi, Ansi: ansi,

View file

@ -48,7 +48,7 @@ type Ansi struct {
format string format string
} }
func (a *Ansi) Init(shellName string) { func (a *Ansi) Init(shellName, goos string) {
a.shell = shellName a.shell = shellName
switch shellName { switch shellName {
case shell.ZSH: case shell.ZSH:
@ -139,10 +139,17 @@ func (a *Ansi) Init(shellName string) {
a.dimmed = "\x1b[2m%s\x1b[22m" a.dimmed = "\x1b[2m%s\x1b[22m"
a.strikethrough = "\x1b[9m%s\x1b[29m" 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<STR>\x1b]8;;(.+)\x1b?(?P<TEXT>.+)\x1b]8;;\x1b\\\\)"
}
} }
func (a *Ansi) InitPlain() { func (a *Ansi) InitPlain(goos string) {
a.Init(shell.PLAIN) a.Init(shell.PLAIN, goos)
} }
func (a *Ansi) GenerateHyperlink(text string) string { func (a *Ansi) GenerateHyperlink(text string) string {

View file

@ -20,7 +20,7 @@ func TestGenerateHyperlinkNoUrl(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
a := Ansi{} a := Ansi{}
a.Init(tc.ShellName) a.Init(tc.ShellName, "")
hyperlinkText := a.GenerateHyperlink(tc.Text) hyperlinkText := a.GenerateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText) assert.Equal(t, tc.Expected, hyperlinkText)
} }
@ -53,7 +53,7 @@ func TestGenerateHyperlinkWithUrl(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
a := Ansi{} a := Ansi{}
a.Init(tc.ShellName) a.Init(tc.ShellName, "")
hyperlinkText := a.GenerateHyperlink(tc.Text) hyperlinkText := a.GenerateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText) assert.Equal(t, tc.Expected, hyperlinkText)
} }
@ -71,7 +71,7 @@ func TestGenerateHyperlinkWithUrlNoName(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
a := Ansi{} a := Ansi{}
a.Init(tc.ShellName) a.Init(tc.ShellName, "")
hyperlinkText := a.GenerateHyperlink(tc.Text) hyperlinkText := a.GenerateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText) assert.Equal(t, tc.Expected, hyperlinkText)
} }
@ -96,7 +96,7 @@ func TestFormatText(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
a := Ansi{} a := Ansi{}
a.InitPlain() a.InitPlain("")
formattedText := a.formatText(tc.Text) formattedText := a.formatText(tc.Text)
assert.Equal(t, tc.Expected, formattedText, tc.Case) assert.Equal(t, tc.Expected, formattedText, tc.Case)
} }
@ -115,7 +115,7 @@ func TestGenerateFileLink(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
a := Ansi{} a := Ansi{}
a.Init(shell.PWSH) a.Init(shell.PWSH, "")
hyperlinkText := a.GenerateHyperlink(tc.Text) hyperlinkText := a.GenerateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText) assert.Equal(t, tc.Expected, hyperlinkText)
} }

View file

@ -37,7 +37,7 @@ func TestMeasureText(t *testing.T) {
for _, shell := range shells { for _, shell := range shells {
for _, tc := range cases { for _, tc := range cases {
ansi := &Ansi{} ansi := &Ansi{}
ansi.Init(shell) ansi.Init(shell, "")
tmpl := &template.Text{ tmpl := &template.Text{
Template: tc.Template, Template: tc.Template,
Env: env, Env: env,

View file

@ -174,7 +174,7 @@ func TestWriteANSIColors(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
ansi := &Ansi{} ansi := &Ansi{}
ansi.Init(shell.PWSH) ansi.Init(shell.PWSH, "")
renderer := &AnsiWriter{ renderer := &AnsiWriter{
Ansi: ansi, Ansi: ansi,
ParentColors: []*Color{tc.Parent}, ParentColors: []*Color{tc.Parent},

View file

@ -62,7 +62,7 @@ func TestGetTitle(t *testing.T) {
Folder: "vagrant", Folder: "vagrant",
}) })
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain("")
ct := &Title{ ct := &Title{
Env: env, Env: env,
Ansi: ansi, Ansi: ansi,
@ -117,7 +117,7 @@ func TestGetConsoleTitleIfGethostnameReturnsError(t *testing.T) {
HostName: "", HostName: "",
}) })
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain("")
ct := &Title{ ct := &Title{
Env: env, Env: env,
Ansi: ansi, Ansi: ansi,

View file

@ -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) { func (b *Block) InitPlain(env platform.Environment, config *Config) {
b.ansi = &color.Ansi{} b.ansi = &color.Ansi{}
b.ansi.InitPlain() b.ansi.InitPlain(b.env.GOOS())
b.writer = &color.AnsiWriter{ b.writer = &color.AnsiWriter{
Ansi: b.ansi, Ansi: b.ansi,
TerminalBackground: shell.ConsoleBackgroundColor(env, config.TerminalBackground), TerminalBackground: shell.ConsoleBackgroundColor(env, config.TerminalBackground),

View file

@ -43,7 +43,7 @@ func (e *Engine) string() string {
return text return text
} }
func (e *Engine) canWriteRPrompt(rprompt bool) bool { func (e *Engine) canWriteRightBlock(rprompt bool) bool {
if rprompt && (e.rprompt == "" || e.Plain) { if rprompt && (e.rprompt == "" || e.Plain) {
return false return false
} }
@ -188,7 +188,7 @@ func (e *Engine) renderBlock(block *Block) {
text, length := block.RenderSegments() text, length := block.RenderSegments()
e.rpromptLength = length e.rpromptLength = length
if !e.canWriteRPrompt(false) { if !e.canWriteRightBlock(false) {
switch block.Overflow { switch block.Overflow {
case Break: case Break:
e.newline() e.newline()
@ -211,7 +211,7 @@ func (e *Engine) renderBlock(block *Block) {
ansi := e.Ansi ansi := e.Ansi
if e.Env.Shell() == shell.BASH { if e.Env.Shell() == shell.BASH {
ansi = &color.Ansi{} ansi = &color.Ansi{}
ansi.InitPlain() ansi.InitPlain(e.Env.GOOS())
} }
prompt := ansi.CarriageForward() prompt := ansi.CarriageForward()
prompt += ansi.GetCursorForRightWrite(length, block.HorizontalOffset) prompt += ansi.GetCursorForRightWrite(length, block.HorizontalOffset)
@ -292,7 +292,7 @@ func (e *Engine) print() string {
prompt += fmt.Sprintf("\nRPROMPT=\"%s\"", e.rprompt) prompt += fmt.Sprintf("\nRPROMPT=\"%s\"", e.rprompt)
return prompt return prompt
case shell.PWSH, shell.PWSH5, shell.PLAIN, shell.NU: case shell.PWSH, shell.PWSH5, shell.PLAIN, shell.NU:
if !e.canWriteRPrompt(true) { if !e.canWriteRightBlock(true) {
break break
} }
e.write(e.Ansi.SaveCursorPosition()) e.write(e.Ansi.SaveCursorPosition())
@ -301,13 +301,13 @@ func (e *Engine) print() string {
e.write(e.rprompt) e.write(e.rprompt)
e.write(e.Ansi.RestoreCursorPosition()) e.write(e.Ansi.RestoreCursorPosition())
case shell.BASH: case shell.BASH:
if !e.canWriteRPrompt(true) { if !e.canWriteRightBlock(true) {
break break
} }
// in bash, the entire rprompt needs to be escaped for the prompt to be interpreted correctly // 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 // see https://github.com/jandedobbeleer/oh-my-posh/pull/2398
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain(e.Env.GOOS())
prompt := ansi.SaveCursorPosition() prompt := ansi.SaveCursorPosition()
prompt += ansi.CarriageForward() prompt += ansi.CarriageForward()
prompt += ansi.GetCursorForRightWrite(e.rpromptLength, 0) prompt += ansi.GetCursorForRightWrite(e.rpromptLength, 0)

View file

@ -40,7 +40,7 @@ func TestCanWriteRPrompt(t *testing.T) {
currentLineLength: tc.PromptLength, currentLineLength: tc.PromptLength,
rprompt: "hello", rprompt: "hello",
} }
got := engine.canWriteRPrompt(true) got := engine.canWriteRightBlock(true)
assert.Equal(t, tc.Expected, got, tc.Case) assert.Equal(t, tc.Expected, got, tc.Case)
} }
} }
@ -72,7 +72,7 @@ func TestPrintPWD(t *testing.T) {
Shell: "shell", Shell: "shell",
}) })
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain("")
engine := &Engine{ engine := &Engine{
Env: env, Env: env,
Config: &Config{ Config: &Config{
@ -102,7 +102,7 @@ func engineRender() {
defer testClearDefaultConfig() defer testClearDefaultConfig()
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain("")
writerColors := cfg.MakeColors() writerColors := cfg.MakeColors()
writer := &color.AnsiWriter{ writer := &color.AnsiWriter{
Ansi: ansi, Ansi: ansi,

View file

@ -33,7 +33,7 @@ func runImageTest(config, content string) (string, error) {
} }
defer os.Remove(file.Name()) defer os.Remove(file.Name())
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.InitPlain() ansi.InitPlain("")
image := &ImageRenderer{ image := &ImageRenderer{
AnsiString: content, AnsiString: content,
Ansi: ansi, Ansi: ansi,

View file

@ -18,11 +18,11 @@ func New(flags *platform.Flags) *Engine {
env.Init() env.Init()
cfg := LoadConfig(env) cfg := LoadConfig(env)
ansi := &color.Ansi{} ansi := &color.Ansi{}
ansi.Init(env.Shell()) ansi.Init(env.Shell(), env.GOOS())
var writer color.Writer var writer color.Writer
if flags.Plain { if flags.Plain {
ansi.InitPlain() ansi.InitPlain(env.GOOS())
writer = &color.PlainWriter{ writer = &color.PlainWriter{
Ansi: ansi, Ansi: ansi,
} }