2020-12-26 10:51:21 -08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"golang.org/x/text/unicode/norm"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ansiFormats struct {
|
|
|
|
shell string
|
|
|
|
linechange string
|
|
|
|
left string
|
|
|
|
right string
|
|
|
|
creset string
|
2020-12-27 02:53:28 -08:00
|
|
|
clearEOL string
|
2020-12-26 10:51:21 -08:00
|
|
|
saveCursorPosition string
|
|
|
|
restoreCursorPosition string
|
|
|
|
title string
|
|
|
|
colorSingle string
|
|
|
|
colorFull string
|
|
|
|
colorTransparent string
|
|
|
|
escapeLeft string
|
|
|
|
escapeRight string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *ansiFormats) init(shell string) {
|
|
|
|
a.shell = shell
|
|
|
|
switch shell {
|
|
|
|
case zsh:
|
|
|
|
a.linechange = "%%{\x1b[%d%s%%}"
|
|
|
|
a.left = "%%{\x1b[%dC%%}"
|
|
|
|
a.right = "%%{\x1b[%dD%%}"
|
|
|
|
a.creset = "%{\x1b[0m%}"
|
2020-12-27 02:53:28 -08:00
|
|
|
a.clearEOL = "%{\x1b[K%}"
|
2020-12-26 10:51:21 -08:00
|
|
|
a.saveCursorPosition = "%{\x1b7%}"
|
|
|
|
a.restoreCursorPosition = "%{\x1b8%}"
|
|
|
|
a.title = "%%{\033]0;%s\007%%}"
|
|
|
|
a.colorSingle = "%%{\x1b[%sm%%}%s%%{\x1b[0m%%}"
|
|
|
|
a.colorFull = "%%{\x1b[%sm\x1b[%sm%%}%s%%{\x1b[0m%%}"
|
|
|
|
a.colorTransparent = "%%{\x1b[%s;49m\x1b[7m%%}%s%%{\x1b[m\x1b[0m%%}"
|
|
|
|
a.escapeLeft = "%{"
|
|
|
|
a.escapeRight = "%}"
|
|
|
|
case bash:
|
|
|
|
a.linechange = "\\[\x1b[%d%s\\]"
|
|
|
|
a.left = "\\[\x1b[%dC\\]"
|
|
|
|
a.right = "\\[\x1b[%dD\\]"
|
|
|
|
a.creset = "\\[\x1b[0m\\]"
|
2020-12-27 02:53:28 -08:00
|
|
|
a.clearEOL = "\\[\x1b[K\\]"
|
2020-12-26 10:51:21 -08:00
|
|
|
a.saveCursorPosition = "\\[\x1b7\\]"
|
|
|
|
a.restoreCursorPosition = "\\[\x1b8\\]"
|
|
|
|
a.title = "\\[\033]0;%s\007\\]"
|
|
|
|
a.colorSingle = "\\[\x1b[%sm\\]%s\\[\x1b[0m\\]"
|
|
|
|
a.colorFull = "\\[\x1b[%sm\x1b[%sm\\]%s\\[\x1b[0m\\]"
|
|
|
|
a.colorTransparent = "\\[\x1b[%s;49m\x1b[7m\\]%s\\[\x1b[m\x1b[0m\\]"
|
|
|
|
a.escapeLeft = "\\["
|
|
|
|
a.escapeRight = "\\]"
|
|
|
|
default:
|
|
|
|
a.linechange = "\x1b[%d%s"
|
|
|
|
a.left = "\x1b[%dC"
|
|
|
|
a.right = "\x1b[%dD"
|
|
|
|
a.creset = "\x1b[0m"
|
2020-12-27 02:53:28 -08:00
|
|
|
a.clearEOL = "\x1b[K"
|
2020-12-26 10:51:21 -08:00
|
|
|
a.saveCursorPosition = "\x1b7"
|
|
|
|
a.restoreCursorPosition = "\x1b8"
|
|
|
|
a.title = "\033]0;%s\007"
|
|
|
|
a.colorSingle = "\x1b[%sm%s\x1b[0m"
|
|
|
|
a.colorFull = "\x1b[%sm\x1b[%sm%s\x1b[0m"
|
|
|
|
a.colorTransparent = "\x1b[%s;49m\x1b[7m%s\x1b[m\x1b[0m"
|
|
|
|
a.escapeLeft = ""
|
|
|
|
a.escapeRight = ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *ansiFormats) lenWithoutANSI(text string) int {
|
|
|
|
rANSI := "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
|
|
|
|
stripped := replaceAllString(rANSI, text, "")
|
|
|
|
stripped = strings.ReplaceAll(stripped, a.escapeLeft, "")
|
|
|
|
stripped = strings.ReplaceAll(stripped, a.escapeRight, "")
|
|
|
|
var i norm.Iter
|
|
|
|
i.InitString(norm.NFD, stripped)
|
|
|
|
var count int
|
|
|
|
for !i.Done() {
|
|
|
|
i.Next()
|
|
|
|
count++
|
|
|
|
}
|
|
|
|
return count
|
|
|
|
}
|