snap command wrongly stacked up the messages while there are CJK characters in the line.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
snapd |
New
|
Undecided
|
Unassigned |
Bug Description
When install/download a snap using `snap install ...`, there will be a progress bar, it is correctly display while in English locale, however, it will stacked up in CJK locale, such as `zh-cn`.
Here is what happened in `zh-cn` locale:
```shell
➜ sudo snap install --edge icalingua
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge"
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 0B/
下载 snap "icalingua" (69),来自频道 "edge" 0% 249kB/
下载 snap "icalingua" (69),来自频道 "edge" 0% 228kB/
下载 snap "icalingua" (69),来自频道 "edge" 0% 210kB/
下载 snap "icalingua" (69),来自频道 "edge" 0% 391kB/
下载 snap "icalingua" (69),来自频道 "edge" 1% 547kB/
下载 snap "icalingua" (69),来自频道 "edge" 1% 684kB/
下载 snap "icalingua" (69),来自频道 "edge" 1% 805kB/
下载 snap "icalingua" (69),来自频道 "edge" 1% 912kB/
下载 snap "icalingua" (69),来自频道 "edge" 2% 1.15MB/
下载 snap "icalingua" (69),来自频道 "edge" 2% 1.37MB/
下载 snap "icalingua" (69),来自频道 "edge" 2% 1.56MB/
下载 snap "icalingua" (69),来自频道 "edge" 3% 1.74MB/
下载 snap "icalingua" (69),来自频道 "edge" 3% 1.90MB/
下载 snap "icalingua" (69),来自频道 "edge" 4% 2.05MB/
下载 snap "icalingua" (69),来自频道 "edge" 4% 2.19MB/
下载 snap "icalingua" (69),来自频道 "edge" 5% 2.32MB/
下载 snap "icalingua" (69),来自频道 "edge" 5% 2.43MB/
下载 snap "icalingua" (69),来自频道 "edge" 5% 2.54MB/
下载 snap "icalingua" (69),来自频道 "edge" 6% 2.64MB/
下载 snap "icalingua" (69),来自频道 "edge" 6% 2.74MB/
下载 snap "icalingua" (69),来自频道 "edge" 7% 2.82MB/
下载 snap "icalingua" (69),来自频道 "edge" 7% 2.91MB/
下载 snap "icalingua" (69),来自频道 "edge" 7% 2.99MB/
下载 snap "icalingua" (69),来自频道 "edge" 8% 3.06MB/
下载 snap "icalingua" (69),来自频道 "edge" 8% 3.13MB/
下载 snap "icalingua" (69),来自频道 "edge" 8% 3.12MB/
下载 snap "icalingua" (69),来自频道 "edge" 9% 3.18MB/
下载 snap "icalingua" (69),来自频道 "edge" 9% 3.31MB/
下载 snap "icalingua" (69),来自频道 "edge" 10% 3.30MB/
下载 snap "icalingua" (69),来自频道 "edge" 10% 3.35MB/
...
下载 snap "icalingua" (69),来自频道 "edge" 95% 4.83MB/
下载 snap "icalingua" (69),来自频道 "edge" 96% 4.83MB/
下载 snap "icalingua" (69),来自频道 "edge" 96% 4.83MB/
下载 snap "icalingua" (69),来自频道 "edge" 96% 4.84MB/
下载 snap "icalingua" (69),来自频道 "edge" 97% 4.84MB/
下载 snap "icalingua" (69),来自频道 "edge" 97% 4.84MB/
下载 snap "icalingua" (69),来自频道 "edge" 98% 4.84MB/
下载 snap "icalingua" (69),来自频道 "edge" 98% 4.84MB/
下载 snap "icalingua" (69),来自频道 "edge" 98% 4.85MB/
下载 snap "icalingua" (69),来自频道 "edge" 99% 4.85MB/
下载 snap "icalingua" (69),来自频道 "edge" 99% 4.85MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.85MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.85MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.83MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.82MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.80MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.78MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.76MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.75MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.73MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.71MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.70MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.68MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.66MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.65MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.63MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.62MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.60MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.58MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.57MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.55MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.54MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.52MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.51MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.49MB/
下载 snap "icalingua" (69),来自频道 "edge" 100% 4.48MB/
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
获取并检查 snap "icalingua" (69) 的断言
将 icalingua:
将 icalingua:
icalingua (edge) 2.4.4-Deus-
```
The reason of it stacked up the messages is that CJK characters are **twice width** of english characters. So, when the `snap` command calculate number of the filling characters, it count the CJK characters as 1 time width, which should be 2.
For example,
`获取并检查 snap "icalingua" (69) 的断言`
The about string is count as width `31`, however, it contains **8 CJK characters**, which should be count as **16** width, so the total width of the string is `39`.
It not only calculate wrongly on the `snap install`, it also stacked the messages on `snap remove ...`.
```shell
➜ sudo snap remove icalingua
将 icalingua:network 从 core:network 断开
将 icalingua:network 从 core:network 断开
将 icalingua:network 从 core:network 断开
将 icalingua:network 从 core:network 断开
将 icalingua:network 从 core:network 断开
将 icalingua:network 从 core:network 断开
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:opengl 从 core:opengl 断开
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:unity7 从 core:unity7 断开
将 icalingua:unity7 从 core:unity7 断开
将 icalingua:unity7 从 core:unity7 断开
将 icalingua:unity7 从 core:unity7 断开
将 icalingua:wayland 从 core:wayland 断开
将 icalingua:wayland 从 core:wayland 断开
将 icalingua:wayland 从 core:wayland 断开
将 icalingua:wayland 从 core:wayland 断开
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:desktop 从 core:desktop 断开
将 icalingua:desktop 从 core:desktop 断开
将 icalingua:desktop 从 core:desktop 断开
将 icalingua:x11 从 core:x11 断开
将 icalingua:x11 从 core:x11 断开
将 icalingua:x11 从 core:x11 断开
将 icalingua:x11 从 core:x11 断开
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:
将 icalingua:home 从 core:home 断开
将 icalingua:home 从 core:home 断开
将 icalingua:gsettings 从 core:gsettings 断开
将 icalingua:gsettings 从 core:gsettings 断开
icalingua removed
```
I checked the 'progress/ ansimeter. go', it is used the number of `rune`, rather than calculate the real width.
https:/ /github. com/snapcore/ snapd/blob/ master/ progress/ ansimeter. go#L150- L160
rpercent := []rune(percent) len(rpercent) -len(rspeed) -len(rtimeleft) , p.label)...)
rspeed := []rune(speed)
rtimeleft := []rune(timeleft)
msg := make([]rune, 0, col)
// XXX: assuming terminal can display `col` number of runes
msg = append(msg, norm(col-
msg = append(msg, rpercent...)
msg = append(msg, rspeed...)
msg = append(msg, rtimeleft...)
i := int(current * float64(col) / p.total)
fmt.Fprint(stdout, "\r", enterReverseMode, string(msg[:i]), exitAttributeMode, string(msg[i:]))
As a reference, here is how project 'schollz/ progressbar' calculating the width:
https:/ /github. com/schollz/ progressbar/ blob/master/ progressbar. go#L647- L651
```go /stackoverflow. com/a/12668840/ 2733724 StringWidth( cleanString)
// get the amount of runes in the string instead of the
// character count of the string, as some runes span multiple characters.
// see https:/
stringWidth := runewidth.
return stringWidth
```
it use `github. com/mattn/ go-runewidth` to calculate the width.