fix: strip ANSI from text before measure

resolves #1744
This commit is contained in:
Jan De Dobbeleer 2022-02-11 20:50:02 +01:00 committed by Jan De Dobbeleer
parent fb1ecb7e66
commit d3d370309f
3 changed files with 19 additions and 10 deletions

View file

@ -10,6 +10,8 @@ const (
zsh = "zsh" zsh = "zsh"
bash = "bash" bash = "bash"
pwsh = "pwsh" pwsh = "pwsh"
AnsiRegex = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
) )
type Ansi struct { type Ansi struct {

View file

@ -7,14 +7,23 @@ import (
) )
func measureText(text string) int { func measureText(text string) int {
// skip hyperlinks // skip strings with ANSI
if !strings.Contains(text, "\x1b]8;;") { if !strings.Contains(text, "\x1b") {
return utf8.RuneCountInString(text) return utf8.RuneCountInString(text)
} }
matches := regex.FindAllNamedRegexMatch(regex.LINK, text) if strings.Contains(text, "\x1b]8;;") {
for _, match := range matches { matches := regex.FindAllNamedRegexMatch(regex.LINK, text)
text = strings.ReplaceAll(text, match["STR"], match["TEXT"]) for _, match := range matches {
text = strings.ReplaceAll(text, match["STR"], match["TEXT"])
}
} }
length := utf8.RuneCountInString(text) text = textWithoutAnsi(text)
return length return utf8.RuneCountInString(text)
}
func textWithoutAnsi(text string) string {
if len(text) == 0 || !strings.Contains(text, "\x1b") {
return text
}
return regex.ReplaceAllString(AnsiRegex, text, "")
} }

View file

@ -68,8 +68,6 @@ const (
lineChange = "linechange" lineChange = "linechange"
consoleTitle = "title" consoleTitle = "title"
link = "link" link = "link"
ansiRegex = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
) )
//go:embed font/Hack-Nerd-Bold.ttf //go:embed font/Hack-Nerd-Bold.ttf
@ -266,7 +264,7 @@ func (ir *ImageRenderer) lenWithoutANSI(text string) int {
for _, match := range matches { for _, match := range matches {
text = strings.ReplaceAll(text, match[str], "") text = strings.ReplaceAll(text, match[str], "")
} }
stripped := regex.ReplaceAllString(ansiRegex, text, "") stripped := regex.ReplaceAllString(color.AnsiRegex, text, "")
length := utf8.RuneCountInString(stripped) length := utf8.RuneCountInString(stripped)
for _, rune := range stripped { for _, rune := range stripped {
length += ir.runeAdditionalWidth(rune) length += ir.runeAdditionalWidth(rune)