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"
bash = "bash"
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 {

View file

@ -7,14 +7,23 @@ import (
)
func measureText(text string) int {
// skip hyperlinks
if !strings.Contains(text, "\x1b]8;;") {
// skip strings with ANSI
if !strings.Contains(text, "\x1b") {
return utf8.RuneCountInString(text)
}
matches := regex.FindAllNamedRegexMatch(regex.LINK, text)
for _, match := range matches {
text = strings.ReplaceAll(text, match["STR"], match["TEXT"])
if strings.Contains(text, "\x1b]8;;") {
matches := regex.FindAllNamedRegexMatch(regex.LINK, text)
for _, match := range matches {
text = strings.ReplaceAll(text, match["STR"], match["TEXT"])
}
}
length := utf8.RuneCountInString(text)
return length
text = textWithoutAnsi(text)
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"
consoleTitle = "title"
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
@ -266,7 +264,7 @@ func (ir *ImageRenderer) lenWithoutANSI(text string) int {
for _, match := range matches {
text = strings.ReplaceAll(text, match[str], "")
}
stripped := regex.ReplaceAllString(ansiRegex, text, "")
stripped := regex.ReplaceAllString(color.AnsiRegex, text, "")
length := utf8.RuneCountInString(stripped)
for _, rune := range stripped {
length += ir.runeAdditionalWidth(rune)