AshlinHarris / Spinners.jl

Command line spinners in Julia with Unicode support
MIT License
13 stars 1 forks source link

Malfunctioning spinners containing "\u3000" #53

Closed AshlinHarris closed 1 year ago

AshlinHarris commented 1 year ago
> There are misfunctionning multi-character spinners (e.g. :fistBump :mindblown) but i dont think it comes from their definitions but rather from the backend. Please take a look at that.

I was able to replicate the issue:

pkg> activate --temp
pkg> add https://github.com/curio-sitas/Spinners.jl#new_spinners
julia> using Spinners
julia> @spinner :fistBump
julia> @spinner :mindblown

Both of these are the only spinners defined with "\u3000".

This reminds me of #13, but I'm not sure it's related. That issue deals with the final cleanup step for characters with varying transcode lengths, but this behavior happens continually. I'm assuming that the correct number of backspaces for "\u3000" isn't being calculated properly.

Originally posted by @AshlinHarris in https://github.com/AshlinHarris/Spinners.jl/issues/52#issuecomment-1265717577

AshlinHarris commented 1 year ago
using Unicode
julia> x = "\u3000"
"ใ€€"

julia> collect(x)
1-element Vector{Char}:
 'ใ€€': Unicode U+3000 (category Zs: Separator, space)

julia> sizeof(x)
3
AshlinHarris commented 1 year ago
julia> c='\u3000'
'ใ€€': Unicode U+3000 (category Zs: Separator, space)

julia> sizeof(c)
4

julia> length(transcode(UInt16, string(c)))
1

Here is the precise issue: To delete characters, backspaces (\b) are printed. Some Unicode characters require multiple backspaces to be erased. I've been calculating the number based on the length of the transcode. However, \u3000 requires 2 backspaces but has a transcode length of 1.

I'm not sure what the best general fix would be. We could eventually use ANSI cursor movements, as this would also make multiple spinners possible.

I'll keep looking for a better Unicode approach, or at least another way to calculate the number of backspaces.

AshlinHarris commented 1 year ago
julia> f(c) = sizeof(c), sizeof("$c"), length(transcode(UInt16, string(c)))
f (generic function with 1 method)

julia> f('๐ŸŽ‰')
(4, 4, 2)

julia> f('ื')
(4, 2, 1)

julia> f('x')
(4, 1, 1)

julia> f('\u3000')
(4, 3, 1)
AshlinHarris commented 1 year ago

For now I'll use erase_character(c) = print("\b"^(sizeof("$c")+1รท2)). It works for @spinner "๐ŸŽ‰\u3000แƒ“\u3000@ " sleep(5), but not on combined marks such as "เค•เคผ".