Skip to content

Commit 0c4f4ab

Browse files
“bingtao”Paperclip-Paperclip
andcommitted
fix(progress): use single-width bar and reset SGR per cell
Avoid wcwidth-2 Unicode blocks breaking carriage-return redraw on some UTF-8/CJK terminals; cap bar width and truncate long labels. Optional NLT_PB_USE_UNICODE=1 restores block glyphs. Co-Authored-By: Paperclip <noreply@paperclip.ing> Made-with: Cursor
1 parent 1d46444 commit 0c4f4ab

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ bash tests/progress_smoke.sh
8686

8787
安装后与其他 lib 一并位于 **`${NLTDEPLOY_ROOT}/libexec/nltdeploy/lib/nlt-progress.sh`**(默认即 `~/.local/nltdeploy/libexec/nltdeploy/lib/nlt-progress.sh`)。开发时可直接 `source` 仓库内 **`scripts/lib/nlt-progress.sh`**
8888

89-
提供 **`nlt_pb_human_bytes`****`nlt_pb_render`** / **`nlt_pb_done`**(TTY 下一行进度条:百分比、已用/ETA、速率与 xfer 大小),以及 **`nlt_pb_curl_to_file <url> <dest> [total_bytes]`**(后台 `curl` 写文件时轮询本地大小并刷新进度;非 TTY 下默认降低日志噪声,可用 **`NLT_PB_LABEL`** 自定义标签)。依赖:Bash 3.2+、`awk``date`、可选 **`curl`**(仅下载辅助函数)。
89+
提供 **`nlt_pb_human_bytes`****`nlt_pb_render`** / **`nlt_pb_done`**(TTY 下一行进度条:百分比、已用/ETA、速率与 xfer 大小),以及 **`nlt_pb_curl_to_file <url> <dest> [total_bytes]`**(后台 `curl` 写文件时轮询本地大小并刷新进度;非 TTY 下默认降低日志噪声,可用 **`NLT_PB_LABEL`** 自定义标签)。条形默认使用 **单宽 ASCII**`#` / `-`),避免在部分 UTF-8/CJK 终端上 Unicode 块字符占双列导致 `\r` 重绘错位;需要 **``/``** 样式时设置 **`NLT_PB_USE_UNICODE=1`**依赖:Bash 3.2+、`awk``date`、可选 **`curl`**(仅下载辅助函数)。
9090

9191
设计说明见 [`docs/superpowers/specs/2026-04-15-war-23-progress-bar-design.md`](docs/superpowers/specs/2026-04-15-war-23-progress-bar-design.md)
9292

scripts/lib/nlt-progress.sh

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,12 @@ _nlt_pb_parse_content_length() {
6363

6464
# nlt_pb_render current_bytes total_bytes label start_epoch
6565
# total_bytes=0 表示总长未知:条形为不确定样式,百分比与 ETA 为 —
66+
# 默认条形字符为单宽 ASCII(# / -),避免在 CJK/UTF-8 终端上 █/░ 被计为双宽列
67+
# 导致 \r 重绘错位、行尾出现“漂移”块字符。需要 Unicode 块时可设 NLT_PB_USE_UNICODE=1。
6668
nlt_pb_render() {
6769
local cur="${1:-0}" total="${2:-0}" label="${3:-}" start="${4:-0}"
6870
local now cols barw filled pct elapsed rate eta rem slot span
69-
local cur_h total_h rate_h line bar i ch color denom
71+
local cur_h total_h rate_h line bar i color denom maxlab ch_f ch_e
7072

7173
[[ "${cur}" =~ ^[0-9]+$ ]] || cur=0
7274
[[ "${total}" =~ ^[0-9]+$ ]] || total=0
@@ -83,9 +85,25 @@ nlt_pb_render() {
8385
fi
8486

8587
cols="$(_nlt_pb_cols)"
86-
barw=$((cols - 52))
87-
[[ "$barw" -lt 12 ]] && barw=12
88-
[[ "$barw" -gt 40 ]] && barw=40
88+
# 为右侧统计、括号与标签预留列;避免整行超过终端宽度导致折行错乱
89+
maxlab=$((cols - 58))
90+
[[ "$maxlab" -lt 10 ]] && maxlab=10
91+
if [[ "${#label}" -gt "$maxlab" ]]; then
92+
label="${label:0:$((maxlab - 3))}..."
93+
fi
94+
95+
barw=$((cols - 56))
96+
[[ "$barw" -lt 8 ]] && barw=8
97+
[[ "$barw" -gt 32 ]] && barw=32
98+
99+
if [[ "${NLT_PB_USE_UNICODE:-}" == "1" ]]; then
100+
ch_f=$''
101+
ch_e=$''
102+
else
103+
ch_f='#'
104+
ch_e='-'
105+
fi
106+
89107
denom=$((barw - 1))
90108
[[ "$denom" -lt 1 ]] && denom=1
91109

@@ -131,21 +149,19 @@ nlt_pb_render() {
131149
if [[ "$i" -lt "$filled" ]]; then
132150
color=$((39 + (i * 6 / denom)))
133151
[[ "$color" -gt 45 ]] && color=45
134-
ch=$''
135-
bar+="$(printf '\033[38;5;%dm%s' "$color" "$ch")"
152+
bar+="$(printf '\033[38;5;%dm%s\033[0m' "$color" "$ch_f")"
136153
else
137-
bar+=$'\033[38;5;238m'
154+
bar+="$(printf '\033[38;5;238m%s\033[0m' "$ch_e")"
138155
fi
139156
done
140157
else
141158
for ((i = 0; i < barw; i++)); do
142159
if [[ "$i" -ge "$slot" && "$i" -lt $((slot + span)) ]]; then
143160
color=$((39 + (i * 6 / denom)))
144161
[[ "$color" -gt 45 ]] && color=45
145-
ch=$''
146-
bar+="$(printf '\033[38;5;%dm%s' "$color" "$ch")"
162+
bar+="$(printf '\033[38;5;%dm%s\033[0m' "$color" "$ch_f")"
147163
else
148-
bar+=$'\033[38;5;238m'
164+
bar+="$(printf '\033[38;5;238m%s\033[0m' "$ch_e")"
149165
fi
150166
done
151167
fi

0 commit comments

Comments
 (0)