From 2553df51f96a84e64d72437ec5aded6a3b442f3a Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Sat, 14 May 2022 20:50:20 +0200 Subject: [PATCH] refactor(text): escape segment text --- src/color/ansi.go | 120 ++---------------------------------------- src/color/writer.go | 1 - src/console/title.go | 1 - src/engine/segment.go | 9 +++- 4 files changed, 11 insertions(+), 120 deletions(-) diff --git a/src/color/ansi.go b/src/color/ansi.go index 9be0cf9c..7e35351f 100644 --- a/src/color/ansi.go +++ b/src/color/ansi.go @@ -38,17 +38,10 @@ type Ansi struct { reverse string dimmed string format string - reservedSequences []sequenceReplacement -} - -type sequenceReplacement struct { - text string - replacement string } func (a *Ansi) Init(shellName string) { a.shell = shellName - a.initEscapeSequences(shellName) switch shellName { case shell.ZSH: a.format = "%%{%s%%}" @@ -129,111 +122,13 @@ func (a *Ansi) Init(shellName string) { a.dimmed = "\x1b[2m%s\x1b[22m" a.strikethrough = "\x1b[9m%s\x1b[29m" } + if shellName == shell.FISH { + a.hyperlink = "\x1b]8;;%s\x1b\\\\%s\x1b]8;;\x1b\\" + } } func (a *Ansi) InitPlain(shellName string) { a.Init(shell.PLAIN) - a.initEscapeSequences(shellName) -} - -func (a *Ansi) initEscapeSequences(shellName string) { - switch shellName { - case shell.ZSH: - // escape double quotes and variable expansion - a.reservedSequences = []sequenceReplacement{ - {text: "`", replacement: "'"}, - {text: `%l`, replacement: `%%l`}, - {text: `%M`, replacement: `%%M`}, - {text: `%m`, replacement: `%%m`}, - {text: `%n`, replacement: `%%n`}, - {text: `%y`, replacement: `%%y`}, - {text: `%#`, replacement: `%%#`}, - {text: `%?`, replacement: `%%?`}, - {text: `%_`, replacement: `%%_`}, - {text: `%^`, replacement: `%%^`}, - {text: `%d`, replacement: `%%d`}, - {text: `%/`, replacement: `%%/`}, - {text: `%~`, replacement: `%%~`}, - {text: `%e`, replacement: `%%e`}, - {text: `%h`, replacement: `%%h`}, - {text: `%!`, replacement: `%%!`}, - {text: `%i`, replacement: `%%i`}, - {text: `%I`, replacement: `%%I`}, - {text: `%j`, replacement: `%%j`}, - {text: `%L`, replacement: `%%L`}, - {text: `%N`, replacement: `%%N`}, - {text: `%x`, replacement: `%%x`}, - {text: `%c`, replacement: `%%c`}, - {text: `%.`, replacement: `%%.`}, - {text: `%C`, replacement: `%%C`}, - {text: `%D`, replacement: `%%D`}, - {text: `%T`, replacement: `%%T`}, - {text: `%t`, replacement: `%%t`}, - {text: `%@`, replacement: `%%@`}, - {text: `%*`, replacement: `%%*`}, - {text: `%w`, replacement: `%%w`}, - {text: `%W`, replacement: `%%W`}, - {text: `%D`, replacement: `%%D`}, - {text: `%B`, replacement: `%%B`}, - {text: `%b`, replacement: `%%b`}, - {text: `%E`, replacement: `%%E`}, - {text: `%U`, replacement: `%%U`}, - {text: `%S`, replacement: `%%S`}, - {text: `%F`, replacement: `%%F`}, - {text: `%K`, replacement: `%%K`}, - {text: `%G`, replacement: `%%G`}, - {text: `%v`, replacement: `%%v`}, - {text: `%(`, replacement: `%%(`}, - } - case shell.BASH: - a.reservedSequences = []sequenceReplacement{ - {text: "`", replacement: "'"}, - {text: `\a`, replacement: `\\a`}, - {text: `\d`, replacement: `\\d`}, - {text: `\D`, replacement: `\\D`}, - {text: `\e`, replacement: `\\e`}, - {text: `\h`, replacement: `\\h`}, - {text: `\H`, replacement: `\\H`}, - {text: `\j`, replacement: `\\j`}, - {text: `\l`, replacement: `\\l`}, - {text: `\n`, replacement: `\\n`}, - {text: `\r`, replacement: `\\r`}, - {text: `\s`, replacement: `\\s`}, - {text: `\t`, replacement: `\\t`}, - {text: `\T`, replacement: `\\T`}, - {text: `\@`, replacement: `\\@`}, - {text: `\A`, replacement: `\\A`}, - {text: `\u`, replacement: `\\u`}, - {text: `\v`, replacement: `\\v`}, - {text: `\V`, replacement: `\\V`}, - {text: `\w`, replacement: `\\w`}, - {text: `\W`, replacement: `\\W`}, - {text: `\!`, replacement: `\\!`}, - {text: `\#`, replacement: `\\#`}, - {text: `\$`, replacement: `\\$`}, - {text: `\nnn`, replacement: `\\nnn`}, - } - case shell.FISH: - a.reservedSequences = []sequenceReplacement{ - {text: "`", replacement: "'"}, - {text: `\a`, replacement: `\\a`}, - {text: `\b`, replacement: `\\b`}, - {text: `\e`, replacement: `\\e`}, - {text: `\f`, replacement: `\\f`}, - {text: `\r`, replacement: `\\r`}, - {text: `\t`, replacement: `\\t`}, - {text: `\v`, replacement: `\\v`}, - {text: `\c`, replacement: `\\c`}, - {text: `\x`, replacement: `\\x`}, - {text: `\X`, replacement: `\\X`}, - {text: `\0`, replacement: `\\0`}, - {text: `\U`, replacement: `\\U`}, - } - default: - a.reservedSequences = []sequenceReplacement{ - {text: "`", replacement: "'"}, - } - } } func (a *Ansi) GenerateHyperlink(text string) string { @@ -307,15 +202,6 @@ func (a *Ansi) ClearAfter() string { return a.clearLine + a.clearBelow } -func (a *Ansi) EscapeText(text string) string { - // what to escape/replace is different per shell - - for _, s := range a.reservedSequences { - text = strings.ReplaceAll(text, s.text, s.replacement) - } - return text -} - func (a *Ansi) Title(title string) string { return fmt.Sprintf(a.title, title) } diff --git a/src/color/writer.go b/src/color/writer.go index 42d9d4d1..b19a603a 100644 --- a/src/color/writer.go +++ b/src/color/writer.go @@ -150,7 +150,6 @@ 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.EscapeText(text) // first we match for any potentially valid colors enclosed in <> // i.e., find color overrides diff --git a/src/console/title.go b/src/console/title.go index 8dea749d..5c9c9332 100644 --- a/src/console/title.go +++ b/src/console/title.go @@ -15,7 +15,6 @@ type Title struct { func (t *Title) GetTitle() string { title := t.getTitleTemplateText() title = t.Ansi.TrimAnsi(title) - title = t.Ansi.EscapeText(title) return t.Ansi.Title(title) } diff --git a/src/engine/segment.go b/src/engine/segment.go index 02f3f5d2..dd7385b4 100644 --- a/src/engine/segment.go +++ b/src/engine/segment.go @@ -357,8 +357,15 @@ func (segment *Segment) SetText() { // this can't happen where we do regular text replacement in ansi.go // as that would also replace valid \[\] sequences and break the prompt // except for git bash on Windows - if segment.env.Shell() == shell.BASH && segment.env.Platform() != environment.WindowsPlatform { + switch segment.env.Shell() { + case shell.BASH, shell.FISH: segment.text = strings.ReplaceAll(segment.text, `\`, `\\`) + case shell.ZSH: + segment.text = strings.ReplaceAll(segment.text, `%`, `%%`) } + segment.text = strings.ReplaceAll(segment.text, "`", "'") + // if segment.env.Shell() == shell.BASH && segment.env.Platform() != environment.WindowsPlatform { + // segment.text = strings.ReplaceAll(segment.text, `\`, `\\`) + // } segment.Enabled = len(strings.ReplaceAll(segment.text, " ", "")) > 0 }