"Visible" length of a unicode string

Is there an easy way to get the visible length of a string? My program returns the following string:

e[0;97;44;1m per e[0;34;104me[0me[0me[0;97;104;1m 2021-11-15 13:06 e[0;94;107me[0me[0me[0;94;107;1m ~/code/goprompt e[0;97;104me[0me[0me[0;97;104;1m go 1.17 e[0;94;44me[0me[0me[0;97;44;1m master|~3 e[0;34me[0me[0m 

This string is over 200 bytes long, but the majority of characters in this string is non-printable characters, like color codes etc. The output in terminal is actually this:

What I am interested in is the length of this prompt in the terminal, so ~67 chars, if I counted correctly. I have tried a few different ways:

	fmt.Println(len(result))                      // returns 229
	fmt.Println(len([]rune(result)))              // returns 219
	fmt.Println(utf8.RuneCountInString(result))   // returns 219

I basically want a utf8.VisibleRuneCountInString(result). Anyone know of such a function?

These terminal escape sequences are specific to Unix shells (and there, probably only specific to a particular shell like bash or zsh). They exist since before the Unicode era, hence Unicode functions like RuneCountInString do not apply here.

You would need a custom length function that is aware of these shell escape sequences and the size of their visual representations in the terminal. Not sure if something like that exists in the wild.

Aha, I understand what you are saying. I will solve it manually then, by counting the length before the coloring is being applied. Sounds doable…thanks!

1 Like

Maybe there are some useful len functions available. A search for escape sequence terminal on pkg.go.dev has a couple of results, including

text package - github.com/MichaelMure/go-term-text - pkg.go.dev

that has a Len() function that ignores escape sequences when counting chars.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.