Give the usage bars a line of their own, always
Squeezing the 5h/7d group onto line one was what cost the reset times and the pace figure at laptop width, and it made the layout jump between one and two lines as the branch name or the cost changed width. Line two is now the group's own at every terminal size, so both timestamps and the burn rate fit; the ladder only starts giving things up below ~80 columns. The bars also survive down to 35 columns now rather than being dropped below 68, since a line of their own is all they need. Every rung of the ladder is fit-checked, the last one included: with the floor that low, a percentage the API reports in more digits than anyone expects would otherwise have overflowed the line rather than dropped the group. The two timestamps still cost ~10 subprocesses to format on a line that redraws per keystroke, so that is skipped when line two provably cannot show them -- an under-estimate, so the fit check stays the decider. With nothing left to squeeze, WRAP_NARROW, the wrap band and the split tier go: line one is the full tier down to 150, wide to 68, then narrow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2a785a55a7
commit
ab96dfc52a
7 changed files with 148 additions and 155 deletions
|
|
@ -11,8 +11,9 @@ SHOW_TOKENS=true # token usage bar
|
||||||
SHOW_THINKING=true # extended thinking indicator
|
SHOW_THINKING=true # extended thinking indicator
|
||||||
SHOW_RATE_LIMITS=true # 5h / 7d rate limit bars
|
SHOW_RATE_LIMITS=true # 5h / 7d rate limit bars
|
||||||
SHOW_MODEL_LIMIT=true # per-model weekly limit bar (e.g. Fable), when the API reports one
|
SHOW_MODEL_LIMIT=true # per-model weekly limit bar (e.g. Fable), when the API reports one
|
||||||
WRAP_NARROW=true # wrap onto a second line rather than dropping segments or being clipped
|
RL_MIN_WIDTH=35 # narrowest usable width the 5h + 7d bars fit on their own
|
||||||
WRAP_MIN_WIDTH=100 # below this, keep wide-tier line-one content (it can wrap)
|
# line: two of "5h ██████ 100%" plus a separator, +4
|
||||||
|
COMPACT_WIDTH=100 # below this, shorten line one to what it has room for
|
||||||
BRANCH_MAX_LEN=28 # truncate branch names longer than this
|
BRANCH_MAX_LEN=28 # truncate branch names longer than this
|
||||||
CWD_MAX_LEN=20 # truncate the cwd basename longer than this
|
CWD_MAX_LEN=20 # truncate the cwd basename longer than this
|
||||||
GIT_CACHE_SECS=10 # seconds to cache git status (git diff is slow on large repos)
|
GIT_CACHE_SECS=10 # seconds to cache git status (git diff is slow on large repos)
|
||||||
|
|
@ -338,8 +339,8 @@ format_reset_time() {
|
||||||
model_name=$(echo "$input" | jq -r '.model.display_name // "Claude"')
|
model_name=$(echo "$input" | jq -r '.model.display_name // "Claude"')
|
||||||
cwd=$(echo "$input" | jq -r '.cwd // empty')
|
cwd=$(echo "$input" | jq -r '.cwd // empty')
|
||||||
cost_usd=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
|
cost_usd=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
|
||||||
# Formatted here rather than where it is rendered: the wrap-mode branch budget
|
# Formatted here rather than where it is rendered: the compact-tier branch
|
||||||
# needs its width, and it is not fixed ("$4.61" vs "$1234.56").
|
# budget needs its width, and it is not fixed ("$4.61" vs "$1234.56").
|
||||||
cost_fmt=""
|
cost_fmt=""
|
||||||
[ -n "$cost_usd" ] && cost_fmt=$(printf '%.2f' "$cost_usd" 2>/dev/null)
|
[ -n "$cost_usd" ] && cost_fmt=$(printf '%.2f' "$cost_usd" 2>/dev/null)
|
||||||
|
|
||||||
|
|
@ -370,8 +371,8 @@ thinking_on=true
|
||||||
[ "$sl_thinking" = "false" ] && thinking_on=false
|
[ "$sl_thinking" = "false" ] && thinking_on=false
|
||||||
|
|
||||||
# The effort level replaces the static "thinking" label. Whitelisted rather
|
# The effort level replaces the static "thinking" label. Whitelisted rather
|
||||||
# than printed as-is: an unrecognised value would escape the width budget that
|
# than printed as-is: an unrecognised value would escape the width budget the
|
||||||
# the wrap branch computes from this string.
|
# compact tier computes from this string.
|
||||||
case "$effort" in
|
case "$effort" in
|
||||||
low|medium|high|xhigh|max) thinking_label="$effort" ;;
|
low|medium|high|xhigh|max) thinking_label="$effort" ;;
|
||||||
*) thinking_label="thinking" ;;
|
*) thinking_label="thinking" ;;
|
||||||
|
|
@ -379,36 +380,28 @@ esac
|
||||||
|
|
||||||
# ===== Adaptive width tiers =====
|
# ===== Adaptive width tiers =====
|
||||||
#
|
#
|
||||||
# Tiers now choose only how much of LINE ONE to show. What the rate-limit
|
# The rate-limit group always gets line two to itself, so tiers choose only how
|
||||||
# group contains, and whether it wraps, is decided by measurement at the end of
|
# much of LINE ONE to show. What that group contains is decided by measurement
|
||||||
# the script, not here -- tiers cannot see how long the branch, cwd or model
|
# at the end of the script, not here -- tiers cannot see how long the branch,
|
||||||
# name is, which is how content used to end up clipped.
|
# cwd or model name is, which is how content used to end up clipped.
|
||||||
#
|
#
|
||||||
# full (≥150): CWD, ahead/behind, "◆ high" effort, cost
|
# full (≥150): CWD, ahead/behind, "◆ high" effort, cost
|
||||||
# wide (100–149): ahead/behind, "◆ high" effort, cost
|
# wide (68–149): the same without the CWD, and below COMPACT_WIDTH with a
|
||||||
# split (76–99): short model, ahead/behind, "◆" symbol
|
# short model name and a branch budgeted to what is left
|
||||||
# (reachable only with WRAP_NARROW=false; otherwise the wrap
|
# narrow (<68): short model + branch + token bar only -- the usage group is
|
||||||
# band below overrides this range to wide)
|
# unaffected, it has its own line at every width
|
||||||
# narrow (<76): short model + branch + token only; no rate limits at all
|
|
||||||
#
|
#
|
||||||
if [ "$USABLE_WIDTH" -ge 150 ] 2>/dev/null; then width_tier="full"
|
if [ "$USABLE_WIDTH" -ge 150 ] 2>/dev/null; then width_tier="full"
|
||||||
elif [ "$USABLE_WIDTH" -ge 100 ] 2>/dev/null; then width_tier="wide"
|
elif [ "$USABLE_WIDTH" -ge 68 ] 2>/dev/null; then width_tier="wide"
|
||||||
elif [ "$USABLE_WIDTH" -ge 76 ] 2>/dev/null; then width_tier="split"
|
|
||||||
else width_tier="narrow"
|
else width_tier="narrow"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Two-line mode. Between WRAP_FLOOR and WRAP_MIN_WIDTH there isn't room for
|
# Compact: the wide tier with a short model name and the branch cut to whatever
|
||||||
# everything on one line, but there IS room across two — so instead of dropping
|
# line one has left. Between 68 and COMPACT_WIDTH columns the wide-tier
|
||||||
# the rate-limit group we break before it and render the wide-tier content.
|
# segments do fit, but only once those two are budgeted rather than assumed.
|
||||||
# Below WRAP_FLOOR the narrow tier applies instead, which drops the rate-limit
|
compact=false
|
||||||
# group entirely -- so there is nothing to wrap and no second line to put it on.
|
if [ "$width_tier" = "wide" ] && [ "$USABLE_WIDTH" -lt "$COMPACT_WIDTH" ] 2>/dev/null; then
|
||||||
WRAP_FLOOR=68
|
compact=true
|
||||||
wrap_mode=false
|
|
||||||
if $WRAP_NARROW \
|
|
||||||
&& [ "$USABLE_WIDTH" -lt "$WRAP_MIN_WIDTH" ] 2>/dev/null \
|
|
||||||
&& [ "$USABLE_WIDTH" -ge "$WRAP_FLOOR" ] 2>/dev/null; then
|
|
||||||
wrap_mode=true
|
|
||||||
width_tier="wide"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Shorten model name for tight spaces
|
# Shorten model name for tight spaces
|
||||||
|
|
@ -428,8 +421,9 @@ out=""
|
||||||
rl_bare=""
|
rl_bare=""
|
||||||
rl_lean=""
|
rl_lean=""
|
||||||
rl_pace=""
|
rl_pace=""
|
||||||
rl_mid=""
|
rl_time=""
|
||||||
rl_rich=""
|
rl_rich=""
|
||||||
|
pace_len=""
|
||||||
|
|
||||||
# Model — color by family
|
# Model — color by family
|
||||||
model_color="$blue"
|
model_color="$blue"
|
||||||
|
|
@ -439,10 +433,9 @@ case "$model_name" in
|
||||||
esac
|
esac
|
||||||
|
|
||||||
display_model="$model_name"
|
display_model="$model_name"
|
||||||
# split/narrow: shorten so the 5h + 7d bars still fit on one line.
|
# A long display name ("Opus 5 (1M context)" is 19 cols) would overflow line
|
||||||
# wrap mode too: it renders wide-tier content at a split-tier width, and a long
|
# one at these widths, so it gives up everything but the family.
|
||||||
# display name ("Opus 5 (1M context)" is 19 cols) would overflow line one.
|
if [ "$width_tier" = "narrow" ] || $compact; then
|
||||||
if [ "$width_tier" = "split" -o "$width_tier" = "narrow" ] || $wrap_mode; then
|
|
||||||
display_model=$(short_model "$model_name")
|
display_model=$(short_model "$model_name")
|
||||||
fi
|
fi
|
||||||
out+="${model_color}$(esc_data "$display_model")${reset}"
|
out+="${model_color}$(esc_data "$display_model")${reset}"
|
||||||
|
|
@ -457,7 +450,6 @@ fi
|
||||||
|
|
||||||
bar_w="$TOKEN_BAR_WIDTH"
|
bar_w="$TOKEN_BAR_WIDTH"
|
||||||
[ "$width_tier" = "wide" ] && bar_w=6
|
[ "$width_tier" = "wide" ] && bar_w=6
|
||||||
[ "$width_tier" = "split" ] && bar_w=5
|
|
||||||
[ "$width_tier" = "narrow" ] && bar_w=4
|
[ "$width_tier" = "narrow" ] && bar_w=4
|
||||||
|
|
||||||
# Git branch + dirty + ahead/behind
|
# Git branch + dirty + ahead/behind
|
||||||
|
|
@ -469,15 +461,14 @@ if $SHOW_GIT && [ -n "$cwd" ]; then
|
||||||
# Progressively tighten branch truncation
|
# Progressively tighten branch truncation
|
||||||
local_max="$BRANCH_MAX_LEN"
|
local_max="$BRANCH_MAX_LEN"
|
||||||
[ "$width_tier" = "wide" ] && local_max=24
|
[ "$width_tier" = "wide" ] && local_max=24
|
||||||
[ "$width_tier" = "split" ] && local_max=18
|
|
||||||
[ "$width_tier" = "narrow" ] && local_max=12
|
[ "$width_tier" = "narrow" ] && local_max=12
|
||||||
# In wrap mode line one is
|
# In compact mode line one is
|
||||||
# model │ ⎇ branch ✔ ↑1 │ <bar> used/total pct% │ ◇ high │ $cost
|
# model │ ⎇ branch ✔ ↑1 │ <bar> used/total pct% │ ◇ high │ $cost
|
||||||
# and the branch gets whatever the rest of it leaves. Everything after
|
# and the branch gets whatever the rest of it leaves. Everything after
|
||||||
# the branch is appended below, so its width is added up here rather
|
# the branch is appended below, so its width is added up here rather
|
||||||
# than assumed: a flat 56 columns was three short of a four-digit cost,
|
# than assumed: a flat 56 columns was three short of a four-digit cost,
|
||||||
# which pushed line one past the edge to be clipped by the renderer.
|
# which pushed line one past the edge to be clipped by the renderer.
|
||||||
if $wrap_mode; then
|
if $compact; then
|
||||||
tail_len=$(( 5 + 2 )) # "│ ⎇ " and the dirty mark
|
tail_len=$(( 5 + 2 )) # "│ ⎇ " and the dirty mark
|
||||||
[ "${g_ahead:-0}" -gt 0 ] && tail_len=$(( tail_len + 2 + ${#g_ahead} ))
|
[ "${g_ahead:-0}" -gt 0 ] && tail_len=$(( tail_len + 2 + ${#g_ahead} ))
|
||||||
[ "${g_behind:-0}" -gt 0 ] && tail_len=$(( tail_len + 2 + ${#g_behind} ))
|
[ "${g_behind:-0}" -gt 0 ] && tail_len=$(( tail_len + 2 + ${#g_behind} ))
|
||||||
|
|
@ -514,18 +505,12 @@ if $SHOW_TOKENS; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Thinking and effort. The diamond is thinking state, the label is the effort
|
# Thinking and effort. The diamond is thinking state, the label is the effort
|
||||||
# level ("thinking" only when the payload reports no level):
|
# level ("thinking" only when the payload reports no level). Hidden at the
|
||||||
# full/wide → "◆ high" / "◇ high" (label)
|
# narrow tier, where line one has no columns to spare.
|
||||||
# split → "◆" / "◇" (symbol only, saves the label's columns)
|
|
||||||
# narrow → hidden
|
|
||||||
if $SHOW_THINKING && [ "$width_tier" != "narrow" ]; then
|
if $SHOW_THINKING && [ "$width_tier" != "narrow" ]; then
|
||||||
out+="${sep}"
|
out+="${sep}"
|
||||||
if $thinking_on; then
|
if $thinking_on; then out+="${amber}◆ ${thinking_label}${reset}"
|
||||||
if [ "$width_tier" = "split" ]; then out+="${amber}◆${reset}"
|
else out+="${dim}◇ ${thinking_label}${reset}"
|
||||||
else out+="${amber}◆ ${thinking_label}${reset}"; fi
|
|
||||||
else
|
|
||||||
if [ "$width_tier" = "split" ]; then out+="${dim}◇${reset}"
|
|
||||||
else out+="${dim}◇ ${thinking_label}${reset}"; fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -535,9 +520,10 @@ if [ -n "$cost_fmt" ] && [ "$width_tier" = "wide" -o "$width_tier" = "full" ]; t
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ===== Rate limits (API, cached USAGE_CACHE_SECS) =====
|
# ===== Rate limits (API, cached USAGE_CACHE_SECS) =====
|
||||||
# Built at every tier except narrow. Which variant is actually emitted,
|
# Always rendered on a line of its own; which variant is emitted is decided by
|
||||||
# and on how many lines, is decided by the measured ladder at the end.
|
# the measured ladder at the end. Skipped below RL_MIN_WIDTH, where not even
|
||||||
if $SHOW_RATE_LIMITS && [ "$width_tier" != "narrow" ]; then
|
# the two bars fit on that line -- and skipping it also means no API call.
|
||||||
|
if $SHOW_RATE_LIMITS && [ "$USABLE_WIDTH" -ge "$RL_MIN_WIDTH" ] 2>/dev/null; then
|
||||||
api_cache="$CACHE_DIR/statusline-usage-cache.json"
|
api_cache="$CACHE_DIR/statusline-usage-cache.json"
|
||||||
fail_marker="$CACHE_DIR/statusline-usage-fail"
|
fail_marker="$CACHE_DIR/statusline-usage-fail"
|
||||||
needs_refresh=true
|
needs_refresh=true
|
||||||
|
|
@ -614,7 +600,6 @@ if $SHOW_RATE_LIMITS && [ "$width_tier" != "narrow" ]; then
|
||||||
|
|
||||||
if [ -n "$usage_data" ] && echo "$usage_data" | jq -e . >/dev/null 2>&1; then
|
if [ -n "$usage_data" ] && echo "$usage_data" | jq -e . >/dev/null 2>&1; then
|
||||||
bar_width=6
|
bar_width=6
|
||||||
[ "$width_tier" = "split" ] && bar_width=4
|
|
||||||
|
|
||||||
# One jq pass for the whole payload. Parsing it field by field meant
|
# One jq pass for the whole payload. Parsing it field by field meant
|
||||||
# ~10 jq processes per render on the same JSON; the status line runs on
|
# ~10 jq processes per render on the same JSON; the status line runs on
|
||||||
|
|
@ -754,14 +739,16 @@ EOF
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Four variants of the rate-limit group, richest first:
|
# Five nested variants of the rate-limit group, each rung giving up the
|
||||||
# rl_rich bars + reset times + pace + extra usage
|
# least useful thing left:
|
||||||
# rl_mid bars + pace + extra usage
|
# rl_rich bars + pace + reset times + extra usage
|
||||||
|
# rl_time bars + pace + reset times
|
||||||
# rl_pace bars + pace
|
# rl_pace bars + pace
|
||||||
# rl_lean bars only
|
# rl_lean bars, per-model included
|
||||||
# The ladder at the end emits the richest one that fits the space it
|
# rl_bare the 5h and 7d bars alone
|
||||||
# has. Keeping a lean variant matters: extra-usage credits add ~30
|
# The ladder at the end emits the richest one that fits line two.
|
||||||
# columns, which can overflow line two on its own.
|
# Keeping the leaner rungs matters: extra-usage credits add ~30 columns
|
||||||
|
# and the two timestamps ~26, either of which can overflow the line.
|
||||||
seg_5h="${dim}5h${reset} $(build_bar "${five_hour_pct:-0}" "$bar_width") ${cyan}${five_hour_pct:-0}%${reset}"
|
seg_5h="${dim}5h${reset} $(build_bar "${five_hour_pct:-0}" "$bar_width") ${cyan}${five_hour_pct:-0}%${reset}"
|
||||||
seg_7d="${sep}${dim}7d${reset} $(build_bar "${seven_day_pct:-0}" "$bar_width") ${cyan}${seven_day_pct:-0}%${reset}"
|
seg_7d="${sep}${dim}7d${reset} $(build_bar "${seven_day_pct:-0}" "$bar_width") ${cyan}${seven_day_pct:-0}%${reset}"
|
||||||
|
|
||||||
|
|
@ -780,8 +767,7 @@ EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# rl_bare drops the per-model bar too: the last thing worth giving up,
|
# rl_bare drops the per-model bar too: the last thing worth giving up,
|
||||||
# and the only way to fit at all when wrapping is disabled and the
|
# and all that fits on a terminal barely wider than the two bars.
|
||||||
# terminal is narrow.
|
|
||||||
#
|
#
|
||||||
# rl_pace is its own rung so pace is given up BEFORE the per-model bar
|
# rl_pace is its own rung so pace is given up BEFORE the per-model bar
|
||||||
# it annotates: a bar with no pace still says something, a pace with no
|
# it annotates: a bar with no pace still says something, a pace with no
|
||||||
|
|
@ -790,59 +776,55 @@ EOF
|
||||||
rl_bare="${seg_5h}${seg_7d}"
|
rl_bare="${seg_5h}${seg_7d}"
|
||||||
rl_lean="${rl_bare}${seg_scoped}"
|
rl_lean="${rl_bare}${seg_scoped}"
|
||||||
rl_pace="${rl_lean}${seg_pace}"
|
rl_pace="${rl_lean}${seg_pace}"
|
||||||
rl_mid="${rl_pace}${seg_extra}"
|
|
||||||
rl_rich="$rl_mid"
|
|
||||||
|
|
||||||
# Formatting the two reset timestamps costs ~10 subprocesses (date has
|
# rl_time interleaves rather than appends: the 5h timestamp sits with
|
||||||
# no portable one-shot form here), so only pay for it when there is a
|
# its own bar, and the 7d one closes the weekly group it shares with
|
||||||
# chance they will be shown: appended to line one, or alone on line two.
|
# the per-model bar and the pace.
|
||||||
# RESET_COST is the combined width of " reset 4:40p.m." and
|
#
|
||||||
# " reset aug 28, 3:00a.m.".
|
# Formatting the pair costs ~10 subprocesses (date has no portable
|
||||||
line1_len=$(vis_len "$out")
|
# one-shot form here) on a line that redraws per keystroke, so it is
|
||||||
mid_len=$(vis_len "$rl_mid")
|
# skipped when line two provably cannot show them. RESET_COST
|
||||||
RESET_COST=30
|
# deliberately UNDER-estimates their combined width -- " ↺ 1:00am" and
|
||||||
if [ $(( line1_len + 3 + mid_len + RESET_COST )) -le "$USABLE_WIDTH" ] \
|
# " ↺ may 4, 1:00am" at their shortest -- so the ladder below, which
|
||||||
|| { $WRAP_NARROW && [ $(( mid_len + RESET_COST )) -le "$USABLE_WIDTH" ]; }; then
|
# measures the real string, stays the thing that decides.
|
||||||
|
RESET_COST=25
|
||||||
|
pace_len=$(vis_len "$rl_pace")
|
||||||
|
rl_time="$rl_pace"
|
||||||
|
if [ $(( pace_len + RESET_COST )) -le "$USABLE_WIDTH" ]; then
|
||||||
five_hour_reset=$(format_reset_time "$five_hour_reset_iso" "time")
|
five_hour_reset=$(format_reset_time "$five_hour_reset_iso" "time")
|
||||||
seven_day_reset=$(format_reset_time "$seven_day_reset_iso" "datetime")
|
seven_day_reset=$(format_reset_time "$seven_day_reset_iso" "datetime")
|
||||||
r5=""; [ -n "$five_hour_reset" ] && r5=" ${dim}↺ ${five_hour_reset}${reset}"
|
r5=""; [ -n "$five_hour_reset" ] && r5=" ${dim}↺ ${five_hour_reset}${reset}"
|
||||||
r7=""; [ -n "$seven_day_reset" ] && r7=" ${dim}↺ ${seven_day_reset}${reset}"
|
r7=""; [ -n "$seven_day_reset" ] && r7=" ${dim}↺ ${seven_day_reset}${reset}"
|
||||||
rl_rich="${seg_5h}${r5}${seg_7d}${seg_scoped}${seg_pace}${r7}${seg_extra}"
|
rl_time="${seg_5h}${r5}${seg_7d}${seg_scoped}${seg_pace}${r7}"
|
||||||
fi
|
fi
|
||||||
|
rl_rich="${rl_time}${seg_extra}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Attach the rate-limit group, emitting the richest layout that fits.
|
# Attach the rate-limit group on a line of its own, emitting the richest
|
||||||
|
# variant that fits it.
|
||||||
#
|
#
|
||||||
# A second line is worth it for the per-model bar and nothing else: rl_bare is
|
# Line two is never shared with line one's segments, however wide the terminal
|
||||||
# the only variant that drops that bar, and it is the whole reason the group is
|
# is. Squeezing the group onto line one is what used to cost the reset times
|
||||||
# worth showing on an account that has one. Reset times and extra-usage credits
|
# and the pace figure on a laptop-width window, and it made the layout jump
|
||||||
# are given up instead of wrapped for, so content is NOT monotone in width -- at
|
# between one and two lines as the branch name or the cost changed width.
|
||||||
# one column narrower, rung 3 stops fitting and the wrap that follows has room
|
# A full line to itself is worth more than the columns it wastes.
|
||||||
# for the timestamps as well. Only wrapping being switched off makes rl_bare the
|
#
|
||||||
# answer.
|
# The extra-usage credits ride on the richest rung alone, so an account with
|
||||||
# 1-4. one line: with resets / with extra usage / with pace / bars + per-model
|
# overage enabled sees them only on a terminal wide enough for the whole group
|
||||||
# 5-8. two lines: same order, line two having room the single line lacked
|
# -- around 110 columns. Below that the reset times win the space: they are the
|
||||||
# 9. one line, bars only -- WRAP_NARROW=false, the least-bad single line
|
# number you act on, the credits the one you read afterwards.
|
||||||
# Every branch is fit-checked, so no layout is chosen that would be clipped by
|
#
|
||||||
# the renderer, whatever the branch name, cwd, model name or extra-usage width.
|
# Every rung is fit-checked, the last one included, so nothing is chosen that
|
||||||
|
# the renderer would clip, whatever the model name, the extra-usage width or
|
||||||
|
# the percentages the API reports. If not even the two bars fit, the group is
|
||||||
|
# dropped rather than overflowed.
|
||||||
if [ -n "$rl_bare" ]; then
|
if [ -n "$rl_bare" ]; then
|
||||||
rich_len=$(vis_len "$rl_rich")
|
if [ "$(vis_len "$rl_rich")" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_rich"
|
||||||
pace_len=$(vis_len "$rl_pace")
|
elif [ "$(vis_len "$rl_time")" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_time"
|
||||||
lean_len=$(vis_len "$rl_lean")
|
|
||||||
if [ $(( line1_len + 3 + rich_len )) -le "$USABLE_WIDTH" ]; then out+="${sep}${rl_rich}"
|
|
||||||
elif [ $(( line1_len + 3 + mid_len )) -le "$USABLE_WIDTH" ]; then out+="${sep}${rl_mid}"
|
|
||||||
elif [ $(( line1_len + 3 + pace_len )) -le "$USABLE_WIDTH" ]; then out+="${sep}${rl_pace}"
|
|
||||||
elif [ $(( line1_len + 3 + lean_len )) -le "$USABLE_WIDTH" ]; then out+="${sep}${rl_lean}"
|
|
||||||
elif $WRAP_NARROW; then
|
|
||||||
if [ "$rich_len" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_rich"
|
|
||||||
elif [ "$mid_len" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_mid"
|
|
||||||
elif [ "$pace_len" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_pace"
|
elif [ "$pace_len" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_pace"
|
||||||
elif [ "$lean_len" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_lean"
|
elif [ "$(vis_len "$rl_lean")" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_lean"
|
||||||
else out+=$'\n'"$rl_bare"
|
elif [ "$(vis_len "$rl_bare")" -le "$USABLE_WIDTH" ]; then out+=$'\n'"$rl_bare"
|
||||||
fi
|
|
||||||
else
|
|
||||||
out+="${sep}${rl_bare}"
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,13 +124,13 @@ out=$(render 245)
|
||||||
|| bad "30min old: refetched, not held for the hour" "$out"
|
|| bad "30min old: refetched, not held for the hour" "$out"
|
||||||
|
|
||||||
# ------------------------------------------------- bars shown => bars refreshed
|
# ------------------------------------------------- bars shown => bars refreshed
|
||||||
# The refresh is gated on the same tier check as the bars themselves, so the
|
# The refresh is gated on the same width check as the bars themselves, so the
|
||||||
# two must agree at every width: wrapped onto line two included, and 68 being
|
# two must agree at every width, 35 being RL_MIN_WIDTH -- the narrowest usable
|
||||||
# WRAP_FLOOR, the narrowest width that still shows them.
|
# width the bars still fit on their own line.
|
||||||
echo
|
echo
|
||||||
echo "Every width that shows the bars refreshes them:"
|
echo "Every width that shows the bars refreshes them:"
|
||||||
|
|
||||||
for u in 245 115 85 68; do
|
for u in 245 115 85 68 50 35; do
|
||||||
cached_response_aged 360
|
cached_response_aged 360
|
||||||
out=$(render "$u")
|
out=$(render "$u")
|
||||||
if case "$out" in *"5h"*) true ;; *) false ;; esac; then
|
if case "$out" in *"5h"*) true ;; *) false ;; esac; then
|
||||||
|
|
@ -141,14 +141,14 @@ for u in 245 115 85 68; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# One column below the wrap floor the group is dropped entirely — nothing is
|
# One column below RL_MIN_WIDTH the group is dropped entirely — nothing is
|
||||||
# shown, so nothing should be paid for either.
|
# shown, so nothing should be paid for either.
|
||||||
cached_response_aged 360
|
cached_response_aged 360
|
||||||
out=$(render 67)
|
out=$(render 34)
|
||||||
case "$out" in *"5h"*) bad "usable 67: no bars at the narrow tier" "$out" ;;
|
case "$out" in *"5h"*) bad "usable 34: no bars below the group's floor" "$out" ;;
|
||||||
*) ok "usable 67: no bars at the narrow tier" ;; esac
|
*) ok "usable 34: no bars below the group's floor" ;; esac
|
||||||
[ "$(calls)" = "0" ] && ok "usable 67: no API call when no bars are shown" \
|
[ "$(calls)" = "0" ] && ok "usable 34: no API call when no bars are shown" \
|
||||||
|| bad "usable 67: no API call when no bars are shown" "$out"
|
|| bad "usable 34: no API call when no bars are shown" "$out"
|
||||||
|
|
||||||
# --------------------------------------------------------- offline retry backoff
|
# --------------------------------------------------------- offline retry backoff
|
||||||
# With no network, curl can burn --max-time 10 before giving up. A failed fetch
|
# With no network, curl can burn --max-time 10 before giving up. A failed fetch
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,12 @@ SCRIPT = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))
|
||||||
BRANCHES = ["main", "feature/some-longer-branch-name",
|
BRANCHES = ["main", "feature/some-longer-branch-name",
|
||||||
"feature/an-extremely-long-branch-name-that-keeps-going-and-going"]
|
"feature/an-extremely-long-branch-name-that-keeps-going-and-going"]
|
||||||
MODELS = ["Opus 5", "Opus 5 (1M context)"]
|
MODELS = ["Opus 5", "Opus 5 (1M context)"]
|
||||||
WIDTHS = range(64, 245, 10)
|
# Starts at the narrowest terminal line ONE fits on with the longest branch
|
||||||
|
# below (measured: 44 usable columns, i.e. 49 with padding 2) -- the pre-existing
|
||||||
|
# narrow-tier floor, which width_test.sh marks XFAIL. Everything above it is
|
||||||
|
# fair game, and that now includes the band from RL_MIN_WIDTH up, where the
|
||||||
|
# usage group is shown but has few columns to spare.
|
||||||
|
WIDTHS = range(49, 245, 10)
|
||||||
# The cwd basename is rendered at the widest layouts and is capped by
|
# The cwd basename is rendered at the widest layouts and is capped by
|
||||||
# CWD_MAX_LEN; vary it, since a long project directory was one of the ways
|
# CWD_MAX_LEN; vary it, since a long project directory was one of the ways
|
||||||
# line one used to overflow.
|
# line one used to overflow.
|
||||||
|
|
|
||||||
|
|
@ -214,8 +214,8 @@ import sys,re,unicodedata
|
||||||
for ln in sys.stdin.read().rstrip('\n').split('\n'):
|
for ln in sys.stdin.read().rstrip('\n').split('\n'):
|
||||||
p=re.sub(r'\033\[[0-9;]*m','',ln)
|
p=re.sub(r'\033\[[0-9;]*m','',ln)
|
||||||
print(sum(2 if unicodedata.east_asian_width(c) in 'WF' else 1 for c in p))"; }
|
print(sum(2 if unicodedata.east_asian_width(c) in 'WF' else 1 for c in p))"; }
|
||||||
over=0; toomany=0; orphan=0; dropped=0; shown=0
|
over=0; toomany=0; orphan=0; dropped=0; shown=0; missing_wide=0
|
||||||
for u in 200 180 160 155 150 145 140 135 130 125 120 116 110 105 100 95 90 85 80 75 70 68; do
|
for u in 200 180 160 155 150 145 140 135 130 125 120 116 110 105 100 95 90 85 80 75 70 68 60 55 50 45 40; do
|
||||||
o=$(render "$MON" 12345 "$u")
|
o=$(render "$MON" 12345 "$u")
|
||||||
ws=$(printf '%s' "$o" | widths)
|
ws=$(printf '%s' "$o" | widths)
|
||||||
while read -r c; do [ "$c" -gt "$u" ] && over=1; done <<< "$ws"
|
while read -r c; do [ "$c" -gt "$u" ] && over=1; done <<< "$ws"
|
||||||
|
|
@ -224,13 +224,18 @@ for u in 200 180 160 155 150 145 140 135 130 125 120 116 110 105 100 95 90 85 80
|
||||||
# be the last thing standing.
|
# be the last thing standing.
|
||||||
case "$o" in
|
case "$o" in
|
||||||
*"%/d"*) shown=1; case "$o" in *Fable*) ;; *) orphan=1 ;; esac ;;
|
*"%/d"*) shown=1; case "$o" in *Fable*) ;; *) orphan=1 ;; esac ;;
|
||||||
*) case "$o" in *Fable*) dropped=1 ;; esac ;;
|
*) case "$o" in *Fable*) dropped=1 ;; esac
|
||||||
|
[ "$u" -ge 68 ] && missing_wide=1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
[ "$over" = 0 ] && ok "no line exceeds the usable width at any width" || bad "no line exceeds the usable width at any width"
|
[ "$over" = 0 ] && ok "no line exceeds the usable width at any width" || bad "no line exceeds the usable width at any width"
|
||||||
[ "$toomany" = 0 ] && ok "never more than two lines" || bad "never more than two lines"
|
[ "$toomany" = 0 ] && ok "never more than two lines" || bad "never more than two lines"
|
||||||
[ "$orphan" = 0 ] && ok "pace never outlives the per-model bar" || bad "pace never outlives the per-model bar"
|
[ "$orphan" = 0 ] && ok "pace never outlives the per-model bar" || bad "pace never outlives the per-model bar"
|
||||||
[ "$shown" = 1 ] && ok "pace is actually rendered somewhere in the sweep" || bad "pace is actually rendered somewhere in the sweep"
|
[ "$shown" = 1 ] && ok "pace is actually rendered somewhere in the sweep" || bad "pace is actually rendered somewhere in the sweep"
|
||||||
|
# Line two is the group's own, so pace survives every width that fits a normal
|
||||||
|
# status line -- it is only given up on a genuinely tiny terminal.
|
||||||
|
[ "$missing_wide" = 0 ] && ok "pace is kept at every width from 68 columns up" \
|
||||||
|
|| bad "pace is kept at every width from 68 columns up"
|
||||||
[ "$dropped" = 1 ] && ok "the pace rung is reachable: some width keeps the bar but drops pace" \
|
[ "$dropped" = 1 ] && ok "the pace rung is reachable: some width keeps the bar but drops pace" \
|
||||||
|| bad "the pace rung is reachable: some width keeps the bar but drops pace"
|
|| bad "the pace rung is reachable: some width keeps the bar but drops pace"
|
||||||
|
|
||||||
|
|
@ -238,7 +243,7 @@ done
|
||||||
# readout, pace is the number this segment exists for, so the credits go first.
|
# readout, pace is the number this segment exists for, so the credits go first.
|
||||||
fixture 7.0 "$R_MON_ISO" "$(scoped 0 null)" "$EXTRA_ON"
|
fixture 7.0 "$R_MON_ISO" "$(scoped 0 null)" "$EXTRA_ON"
|
||||||
pace_alone=0; credits_alone=0
|
pace_alone=0; credits_alone=0
|
||||||
for u in 200 180 160 155 150 145 140 135 130 125 120 116 110 105 100 95 90 85 80 75 70 68; do
|
for u in 200 180 160 155 150 145 140 135 130 125 120 116 110 105 100 95 90 85 80 75 70 68 60 55 50 45 40; do
|
||||||
o=$(render "$MON" 12345 "$u")
|
o=$(render "$MON" 12345 "$u")
|
||||||
case "$o" in
|
case "$o" in
|
||||||
*"%/d"*) case "$o" in *extra*) ;; *) pace_alone=1 ;; esac ;;
|
*"%/d"*) case "$o" in *extra*) ;; *) pace_alone=1 ;; esac ;;
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,25 @@ out=$(render 250)
|
||||||
case "$out" in *"Fable"*"10%"*) ok "wide: renders 'Fable' with its percentage" ;;
|
case "$out" in *"Fable"*"10%"*) ok "wide: renders 'Fable' with its percentage" ;;
|
||||||
*) bad "wide: renders 'Fable' with its percentage" "$out" ;; esac
|
*) bad "wide: renders 'Fable' with its percentage" "$out" ;; esac
|
||||||
|
|
||||||
# Wrapped: assert Fable is on line TWO specifically, not merely present.
|
# The usage group always gets a line of its own, however wide the terminal is.
|
||||||
out=$(render 90)
|
for w in 250 116 90; do
|
||||||
[ "$(count "$out")" = "2" ] && ok "narrow: wraps to two lines" || bad "narrow: wraps to two lines" "$out"
|
out=$(render "$w")
|
||||||
case "$(nth "$out" 2)" in *"Fable"*"10%"*) ok "narrow: Fable is on line two" ;;
|
[ "$(count "$out")" = "2" ] && ok "width $w: usage is on its own line" \
|
||||||
*) bad "narrow: Fable is on line two" "$out" ;; esac
|
|| bad "width $w: usage is on its own line" "$out"
|
||||||
case "$(nth "$out" 1)" in *"Fable"*) bad "narrow: Fable not duplicated on line one" "$out" ;;
|
case "$(nth "$out" 2)" in *"Fable"*"10%"*) ok "width $w: Fable is on line two" ;;
|
||||||
*) ok "narrow: Fable not duplicated on line one" ;; esac
|
*) bad "width $w: Fable is on line two" "$out" ;; esac
|
||||||
|
case "$(nth "$out" 1)" in *"Fable"*) bad "width $w: Fable not duplicated on line one" "$out" ;;
|
||||||
|
*) ok "width $w: Fable not duplicated on line one" ;; esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# A line of its own is what buys room for the reset times: both the 5-hour
|
||||||
|
# clock time and the 7-day date survive down to a laptop-sized terminal, where
|
||||||
|
# they used to be the first thing given up.
|
||||||
|
for w in 250 116 100; do
|
||||||
|
out=$(render "$w")
|
||||||
|
case "$(nth "$out" 2)" in *"↺"*"↺"*) ok "width $w: both reset times are shown" ;;
|
||||||
|
*) bad "width $w: both reset times are shown" "$out" ;; esac
|
||||||
|
done
|
||||||
|
|
||||||
# The per-model bar is the reason the group exists on a Fable-capable account,
|
# The per-model bar is the reason the group exists on a Fable-capable account,
|
||||||
# so it must survive by wrapping and never be dropped to squeeze the group onto
|
# so it must survive by wrapping and never be dropped to squeeze the group onto
|
||||||
|
|
@ -105,7 +117,7 @@ for desc in "no limits key:{$BASE,\"extra_usage\":{\"is_enabled\":false}}" \
|
||||||
name="${desc%%:*}"; json="${desc#*:}"
|
name="${desc%%:*}"; json="${desc#*:}"
|
||||||
printf '%s' "$json" | fixture
|
printf '%s' "$json" | fixture
|
||||||
out=$(render 250)
|
out=$(render 250)
|
||||||
if [ "$(count "$out")" = "1" ] && case "$out" in *"5h"*"7d"*) true;; *) false;; esac \
|
if [ "$(count "$out")" = "2" ] && case "$(nth "$out" 2)" in *"5h"*"7d"*) true;; *) false;; esac \
|
||||||
&& case "$out" in *error*|*null*|*"jq:"*|*"line "*) false;; *) true;; esac; then
|
&& case "$out" in *error*|*null*|*"jq:"*|*"line "*) false;; *) true;; esac; then
|
||||||
ok "$name"
|
ok "$name"
|
||||||
else bad "$name" "$out"; fi
|
else bad "$name" "$out"; fi
|
||||||
|
|
@ -139,33 +151,17 @@ fixture <<JSON
|
||||||
"limits":[{"kind":"weekly_scoped","percent":10,"scope":{"model":{"display_name":"A\nB"}},"is_active":true}]}
|
"limits":[{"kind":"weekly_scoped","percent":10,"scope":{"model":{"display_name":"A\nB"}},"is_active":true}]}
|
||||||
JSON
|
JSON
|
||||||
out=$(render 250)
|
out=$(render 250)
|
||||||
[ "$(count "$out")" = "1" ] && ok "newline in display_name does not split the line" \
|
[ "$(count "$out")" = "2" ] && ok "newline in display_name does not split the line" \
|
||||||
|| bad "newline in display_name does not split the line" "$out"
|
|| bad "newline in display_name does not split the line" "$out"
|
||||||
fixture <<JSON
|
fixture <<JSON
|
||||||
{$BASE,"extra_usage":{"is_enabled":false},"limits":[]}
|
{$BASE,"extra_usage":{"is_enabled":false},"limits":[]}
|
||||||
JSON
|
JSON
|
||||||
mkdir -p "$REPO/sub"
|
mkdir -p "$REPO/sub"
|
||||||
out=$(render 250 "$REPO/pro\\nj")
|
out=$(render 250 "$REPO/pro\\nj")
|
||||||
[ "$(count "$out")" = "1" ] && ok "literal backslash-n in cwd does not split the line" \
|
[ "$(count "$out")" = "2" ] && ok "literal backslash-n in cwd does not split the line" \
|
||||||
|| bad "literal backslash-n in cwd does not split the line" "$out"
|
|| bad "literal backslash-n in cwd does not split the line" "$out"
|
||||||
out=$(render 250 "$REPO" 'Opus\n5')
|
out=$(render 250 "$REPO" 'Opus\n5')
|
||||||
[ "$(count "$out")" = "1" ] && ok "literal backslash-n in model name does not split the line" \
|
[ "$(count "$out")" = "2" ] && ok "literal backslash-n in model name does not split the line" \
|
||||||
|| bad "literal backslash-n in model name does not split the line" "$out"
|
|| bad "literal backslash-n in model name does not split the line" "$out"
|
||||||
|
|
||||||
# --------------------------------------------- WRAP_NARROW=false (regression §2)
|
|
||||||
echo "With WRAP_NARROW=false the single line must still be fit-checked:"
|
|
||||||
NOWRAP=$(mktemp); sed 's/^WRAP_NARROW=true/WRAP_NARROW=false/' "$SCRIPT" > "$NOWRAP"
|
|
||||||
fixture <<JSON
|
|
||||||
{$BASE,"extra_usage":{"is_enabled":false},
|
|
||||||
"limits":[{"kind":"weekly_scoped","percent":10,"scope":{"model":{"display_name":"Fable"}},"is_active":true}]}
|
|
||||||
JSON
|
|
||||||
for w in 81 105 130; do
|
|
||||||
out=$(stdin_json "$REPO" "Opus 5" | TERM_WIDTH=$w bash "$NOWRAP" 2>&1 | sed $'s/\033\[[0-9;]*m//g')
|
|
||||||
u=$(( w - 5 )); c=$(vis "$out")
|
|
||||||
[ "$(count "$out")" = "1" ] && [ "$c" -le "$u" ] \
|
|
||||||
&& ok "width $w: one line, $c <= usable $u" \
|
|
||||||
|| bad "width $w: one line within usable $u (got $(count "$out") line/s, $c cols)" "$out"
|
|
||||||
done
|
|
||||||
rm -f "$NOWRAP"
|
|
||||||
|
|
||||||
echo; echo "pass=$pass fail=$fail"; [ "$fail" -eq 0 ]
|
echo; echo "pass=$pass fail=$fail"; [ "$fail" -eq 0 ]
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,10 @@ echo "Fallbacks and tiers:"
|
||||||
has true "" "◆ thinking" 200 "absent effort falls back to the old label"
|
has true "" "◆ thinking" 200 "absent effort falls back to the old label"
|
||||||
has true garbage "◆ thinking" 200 "an unrecognised level falls back rather than widening the line"
|
has true garbage "◆ thinking" 200 "an unrecognised level falls back rather than widening the line"
|
||||||
has true high "◆ high" 120 "the label survives the wide tier"
|
has true high "◆ high" 120 "the label survives the wide tier"
|
||||||
# The split tier (76-99) is unreachable while WRAP_NARROW=true -- that band is
|
# Below 68 columns the narrow tier drops the segment entirely; between there
|
||||||
# overridden to wide and wrapped -- so only narrow is asserted here.
|
# and 100 the compact tier keeps the label, since the usage group has moved off
|
||||||
|
# line one and left room for it.
|
||||||
|
has true high "◆ high" 85 "the label survives the compact tier"
|
||||||
lacks true high "◆" 60 "narrow tier hides the segment"
|
lacks true high "◆" 60 "narrow tier hides the segment"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,13 @@ check() { # usable, branch, model, cost, [xfail-reason]
|
||||||
[ "$over" = "1" ] && why="line exceeds usable width"
|
[ "$over" = "1" ] && why="line exceeds usable width"
|
||||||
# INVARIANT 2: at most two lines
|
# INVARIANT 2: at most two lines
|
||||||
[ "$n" -gt 2 ] && why="${why:-more than two lines}"
|
[ "$n" -gt 2 ] && why="${why:-more than two lines}"
|
||||||
# INVARIANT 3: only wrap when it was actually necessary
|
# INVARIANT 3: the usage group always gets a line of its own, so that the
|
||||||
if [ -z "$why" ] && [ "$n" = "2" ]; then
|
# reset times and the pace figure have room whatever line one holds. Below
|
||||||
local l1 l2; l1=$(printf '%s\n' "$ws" | sed -n 1p); l2=$(printf '%s\n' "$ws" | sed -n 2p)
|
# RL_MIN_WIDTH there is no group to wrap, so a single line is expected.
|
||||||
[ $(( l1 + 3 + l2 )) -le "$u" ] && why="wrapped unnecessarily (would have fit on one line)"
|
if [ -z "$why" ]; then
|
||||||
|
if [ "$u" -ge 35 ] && [ "$n" != "2" ]; then why="usage not on its own line"
|
||||||
|
elif [ "$u" -lt 35 ] && [ "$n" != "1" ]; then why="wrapped with no usage group"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local label="usable=$u branch=${#branch}ch model='${model:0:12}' lines=$n max=$mx"
|
local label="usable=$u branch=${#branch}ch model='${model:0:12}' lines=$n max=$mx"
|
||||||
|
|
@ -75,7 +78,7 @@ M1="Opus 5"
|
||||||
M2="Opus 5 (1M context)"
|
M2="Opus 5 (1M context)"
|
||||||
|
|
||||||
echo "Sweep of usable widths, short branch:"
|
echo "Sweep of usable widths, short branch:"
|
||||||
for u in 200 155 150 130 116 110 100 95 85 75 68 67 60 40; do check "$u" "$SHORT" "$M1" 0.50; done
|
for u in 200 155 150 130 116 110 100 95 85 75 68 67 60 50 40; do check "$u" "$SHORT" "$M1" 0.50; done
|
||||||
# Narrow tier has a ~35-col floor; nothing can fit below that. Verified byte-identical
|
# Narrow tier has a ~35-col floor; nothing can fit below that. Verified byte-identical
|
||||||
# on the pre-change script, so not a regression.
|
# on the pre-change script, so not a regression.
|
||||||
check 25 "$SHORT" "$M1" 0.50 "narrow tier floor ~35 cols"
|
check 25 "$SHORT" "$M1" 0.50 "narrow tier floor ~35 cols"
|
||||||
|
|
@ -86,7 +89,7 @@ for u in 200 150 116 100 85 68; do check "$u" "$LONG" "$M2" 4.61; done
|
||||||
check 40 "$LONG" "$M2" 4.61 "narrow tier floor ~43 cols with a long branch"
|
check 40 "$LONG" "$M2" 4.61 "narrow tier floor ~43 cols with a long branch"
|
||||||
echo "Large cost figure:"
|
echo "Large cost figure:"
|
||||||
for u in 116 85 68; do check "$u" "$SHORT" "$M1" 1234.56; done
|
for u in 116 85 68; do check "$u" "$SHORT" "$M1" 1234.56; done
|
||||||
# ... and with a long branch, which is what makes the wrap-mode branch budget
|
# ... and with a long branch, which is what makes the compact-tier branch budget
|
||||||
# bite: a four-digit cost is three columns wider than the budget assumed.
|
# bite: a four-digit cost is three columns wider than the budget assumed.
|
||||||
echo "Large cost figure with a long branch:"
|
echo "Large cost figure with a long branch:"
|
||||||
for u in 68 69 70 75 85; do check "$u" "$LONG" "$M1" 1234.56; done
|
for u in 68 69 70 75 85; do check "$u" "$LONG" "$M1" 1234.56; done
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue