Skip to content

Commit ec89a7c

Browse files
committed
Use column to layout footer
Realistically, we only need to print a footer in two modes: 1) using the explicit column layout designated by the caller - typically three columns with equal padding in columns 2) using a single column, due to a narrow screen `column` supports both of these use cases by padding columnar data (as indicated by embedded line returns in stdin). item1:item2:item3 item4::item5 Would result in two rows with three columns. The second row would have an empty middle column. By simply replacing ':' with a line return, we can force everything into a single column. `column` is not provided by BusyBox, but is part of util-linux. If the binary is not found on the host system at build time it is internally disabled via the `HAS_COLUMN` use flag. A subset of text is used on each screen in that condition, or if the width is less than 80 characters. Closes #254 Closes #256
1 parent 489fa37 commit ec89a7c

File tree

2 files changed

+59
-103
lines changed

2 files changed

+59
-103
lines changed

zfsbootmenu/install-helpers.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ zfsbootmenu_essential_binaries=(
2424
"tac"
2525
"blkid"
2626
"awk"
27-
"fold"
2827
"ps"
2928
"env"
3029
"chmod"
@@ -42,6 +41,7 @@ zfsbootmenu_essential_binaries=(
4241
# shellcheck disable=SC2034
4342
zfsbootmenu_optional_binaries=(
4443
"mbuffer"
44+
"column"
4545
)
4646

4747
# shellcheck disable=SC2034
@@ -90,6 +90,11 @@ create_zbm_conf() {
9090
has_refresh=1
9191
fi
9292

93+
local has_column
94+
if command -v column >/dev/null 2>&1 ; then
95+
has_column=1
96+
fi
97+
9398
cat > "${BUILDROOT}/etc/zfsbootmenu.conf" <<-'EOF'
9499
# Include guard
95100
[ -n "${_ETC_ZFSBOOTMENU_CONF}" ] && return
@@ -99,6 +104,7 @@ create_zbm_conf() {
99104
cat >> "${BUILDROOT}/etc/zfsbootmenu.conf" <<-EOF
100105
export BYTE_ORDER="${endian:-le}"
101106
export HAS_REFRESH="${has_refresh}"
107+
export HAS_COLUMN="${has_column}"
102108
EOF
103109
}
104110

zfsbootmenu/lib/zfsbootmenu-lib.sh

Lines changed: 52 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -32,99 +32,30 @@ csv_cat() {
3232
(IFS=',' ; printf '%s' "${CSV[*]}")
3333
}
3434

35-
# arg1...argN: tokens to wrap
36-
# prints: string, wrapped to width without breaking tokens
35+
# arg1: colon-delimited string
36+
# arg2: short string used when column is missing / display is small
37+
# prints: string, columnized
3738
# returns: nothing
3839

39-
header_wrap() {
40-
local hardbreak tokens tok footer nlines allow_breaks maxcols curcols
41-
42-
# Pick a wrap width if none was specified
43-
if [ -z "${wrap_width}" ]; then
44-
wrap_width="$(( $( tput cols 2>/dev/null ) - 4 ))"
45-
[ "${wrap_width}" -gt 0 ] || wrap_width=80
46-
fi
47-
48-
# Pick a uniform field width
49-
if [ -z "${field_width}" ]; then
50-
field_width=0
51-
for tok in "$@"; do
52-
[ "${#tok}" -gt "${field_width}" ] && field_width="${#tok}"
53-
done
54-
fi
55-
56-
# Determine maximum number of columns
57-
maxcols=0
58-
curcols=0
59-
for tok in "$@"; do
60-
if [ -z "${tok}" ]; then
61-
if [ "${curcols}" -gt "${maxcols}" ]; then
62-
maxcols="${curcols}"
63-
fi
64-
curcols=0
65-
else
66-
(( curcols=curcols+1 ))
67-
fi
68-
done
69-
70-
# Honor hard breaks only if terminal is sufficiently tall and wide
71-
nlines="$( tput lines 2>/dev/null )" || nlines=0
72-
if [ "${nlines}" -ge 24 ] && [ "${wrap_width}" -ge "$(( maxcols * field_width ))" ]; then
73-
allow_breaks=1
74-
else
75-
allow_breaks=0
40+
column_wrap() {
41+
local footer
42+
footer="${1}"
43+
44+
if [ "${COLUMNS}" -lt 80 ] || [ -z "${HAS_COLUMN}" ] ; then
45+
# Use shorter footer text, if it exists
46+
[ -n "${2}" ] && footer="${2}"
47+
shopt -s extglob
48+
# Collapse repeated colons into a single
49+
footer="${footer//+([:])/:}"
50+
footer="${footer//:/$'\n'}"
51+
shopt -u extglob
52+
else
53+
footer="$( echo -e "${footer}" | column -t -s ':' )"
7654
fi
7755

78-
# Processing is done line-by-line
79-
while [ $# -gt 0 ]; do
80-
hardbreak=0
81-
tokens=()
82-
83-
# Process up to the first empty string, which is a hard break
84-
while [ $# -gt 0 ]; do
85-
# Pad fields if a uniform field width was assigned
86-
if [ "${field_width}" -gt 0 ] && [ -n "$1" ]; then
87-
tok="$( printf "%-${field_width}s" "$1" )"
88-
tok="${tok// /_}"
89-
else
90-
tok="${1// /_}"
91-
fi
92-
93-
shift
94-
95-
if [ -n "${tok}" ]; then
96-
# If breaks are disallowed, also suppress all-empty tokens
97-
[ "${allow_breaks}" -eq 1 ] || [ -n "${tok//_/}" ] || continue;
98-
tokens+=( "${tok}" )
99-
elif [ "${allow_breaks}" -eq 1 ]; then
100-
# Hard wrap on empty tokens only with sufficient space
101-
hardbreak=1
102-
break
103-
fi
104-
done
105-
106-
# Print the header if there were tokens
107-
if [ "${#tokens[@]}" -gt 0 ]; then
108-
# Only try to wrap if the width is long enough
109-
if [ "${wrap_width}" -gt 0 ]; then
110-
[ "$(( field_width + 4 ))" -ge "${wrap_width}" ] && footer="${footer//_/ }"
111-
footer="$( echo -n -e "${tokens[@]}" | fold -s -w "${wrap_width}" )"
112-
else
113-
footer="$( echo -n -e "${tokens[@]}" )"
114-
fi
115-
116-
# Add some color for emphasis
117-
footer="${footer//\[/\\033\[0;32m\[}"
118-
footer="${footer//\]/\]\\033\[0m}"
119-
120-
echo -n -e "${footer//_/ }"
121-
fi
122-
123-
# Add a hard break if an empty token was provided
124-
if [ "${hardbreak}" -ne 0 ]; then
125-
echo ""
126-
fi
127-
done
56+
footer="${footer//\[/\\033\[0;32m\[}"
57+
footer="${footer//\]/\]\\033\[0m}"
58+
echo -e "${footer}"
12859
}
12960

13061
# arg1: Path to file with detected boot environments, 1 per line
@@ -147,11 +78,15 @@ draw_be() {
14778

14879
zdebug "using environment file: ${env}"
14980

150-
header="$( header_wrap \
151-
"[RETURN] boot" "[ESCAPE] refresh view" "[CTRL+P] pool status" "" \
152-
"[CTRL+D] set bootfs" "[CTRL+S] snapshots" "[CTRL+K] kernels" "" \
153-
"[CTRL+E] edit kcl" "[CTRL+J] jump into chroot" "[CTRL+R] recovery shell" "" \
154-
"[CTRL+L] view logs" " " "[CTRL+H] help" )"
81+
header="$( column_wrap "\
82+
[RETURN] boot:[ESCAPE] refresh view:[CTRL+P] pool status
83+
[CTRL+D] set bootfs:[CTRL+S] snapshots:[CTRL+K] kernels
84+
[CTRL+E] edit kcl:[CTRL+J] jump into chroot:[CTRL+R] recovery shell
85+
[CTRL+L] view logs::[CTRL+H] help" \
86+
"\
87+
[RETURN] boot
88+
[CTRL+R] recovery shell
89+
[CTRL+H] help" )"
15590

15691
expects="--expect=alt-e,alt-k,alt-d,alt-s,alt-c,alt-r,alt-p,alt-w,alt-j,alt-o"
15792

@@ -191,9 +126,14 @@ draw_kernel() {
191126

192127
zdebug "using kernels file: ${_kernels}"
193128

194-
header="$( header_wrap "[RETURN] boot" "[ESCAPE] back" "" \
195-
"[CTRL+D] set default" "[CTRL+U] unset default" "" \
196-
"[CTRL+L] view logs" "[CTRL+H] help" )"
129+
header="$( column_wrap "\
130+
[RETURN] boot:[ESCAPE] back
131+
[CTRL+D] set default:[CTRL+U] unset default
132+
[CTRL+L] view logs:[CTRL+H] help" \
133+
"\
134+
[RETURN] boot
135+
[CTRL+D] set default
136+
[CTRL+H] help" )"
197137

198138
expects="--expect=alt-d,alt-u"
199139

@@ -229,9 +169,16 @@ draw_snapshots() {
229169

230170
sort_key="$( get_sort_key )"
231171

232-
header="$( header_wrap "[RETURN] duplicate" "[CTRL+C] clone only" "[CTRL+X] clone and promote" "" \
233-
"[CTRL+N] create new snapshot" "[CTRL+J] jump into chroot" "[CTRL+D] show diff" "" \
234-
"[CTRL+L] view logs" " " "[CTRL+H] help" "" "[ESCAPE] back" " " "[CTRL+R] rollback" )"
172+
header="$( column_wrap "\
173+
[RETURN] duplicate:[CTRL+C] clone only:[CTRL+X] clone and promote
174+
[CTRL+D] show diff:[CTRL+R] rollback:[CTRL+N] create new snapshot
175+
[CTRL+L] view logs::[CTRL+J] jump into chroot
176+
[CTRL+H] help::[ESCAPE] back" \
177+
"\
178+
[RETURN] duplicate
179+
[CTRL+D] show diff
180+
[CTRL+H] help" )"
181+
235182
context="Note: for diff viewer, use tab to select/deselect up to two items"
236183

237184
expects="--expect=alt-x,alt-c,alt-j,alt-o,alt-n,alt-r"
@@ -349,8 +296,11 @@ draw_pool_status() {
349296
[ "${psize}" -le 0 ] && psize=10
350297

351298
# Override uniform field width to force once item per line
352-
header="$( field_width=0 header_wrap "[ESCAPE] back" "" \
353-
"[CTRL+R] rewind checkpoint" "" "[CTRL+L] view logs" "" "[CTRL+H] help" )"
299+
header="$( column_wrap "\
300+
[ESCAPE] back
301+
[CTRL+R] rewind checkpoint
302+
[CTRL+L] view logs
303+
[CTRL+H] help" )"
354304

355305
if ! selected="$( zpool list -H -o name |
356306
HELP_SECTION=zpool-health ${FUZZYSEL} \

0 commit comments

Comments
 (0)