@@ -112,63 +112,93 @@ csv_cat() {
112112# returns: nothing
113113
114114header_wrap () {
115- local tokens footer
115+ local hardbreak tokens tok footer nlines
116116
117- # Nothing to print if there is no header
118- [ $# -gt 0 ] || return
117+ # Pick a wrap width if none was specified
118+ [ -n " $wrap_width " ] || wrap_width= " $(( $( tput cols ) - 4 )) "
119119
120- # Encode spaces in tokens so wrap won't break them
120+ nlines=" $( tput lines 2> /dev/null ) " || nlines=0
121+
122+ # Processing is done line-by-line
121123 while [ $# -gt 0 ]; do
122- tokens+=( " ${1// / _} " )
123- shift
124- done
124+ hardbreak=0
125+ tokens=()
126+
127+ # Process up to the first empty string, which is a hard break
128+ while [ $# -gt 0 ]; do
129+ tok=" ${1// / _} "
130+ shift
131+
132+ if [ -n " ${tok} " ]; then
133+ tokens+=( " ${tok} " )
134+ elif [ " $nlines " -ge 24 ]; then
135+ # Hard wrap on empty tokens only with sufficient space
136+ hardbreak=1
137+ break
138+ fi
139+ done
125140
126- # Pick a wrap width if none was specified
127- [ -n " $wrap_width " ] || wrap_width=" $(( $( tput cols ) - 4 )) "
141+ # Print the header if there were tokens
142+ if [ " ${# tokens[@]} " -gt 0 ]; then
143+ # Only try to wrap if the width is long enough
144+ if [ " ${wrap_width} " -gt 0 ]; then
145+ footer=" $( echo -n -e " ${tokens[@]} " | fold -s -w " ${wrap_width} " ) "
146+ else
147+ footer=" $( echo -n -e " ${tokens[@]} " ) "
148+ fi
149+
150+ # Add some color for emphasis
151+ footer=" ${footer// \[ / \\ 033\[ 0;32m\[ } "
152+ footer=" ${footer// \] / \]\\ 033\[ 0m} "
153+
154+ echo -n -e " ${footer// _/ } "
155+ fi
128156
129- footer=" $( echo -n -e " ${tokens[@]} " | fold -s -w " ${wrap_width} " ) "
130- footer=" ${footer// \[ / \\ 033\[ 0;32m\[ } "
131- footer=" ${footer// \] / \]\\ 033\[ 0m} "
132- echo -n -e " ${footer// _/ } "
157+ # Add a hard break if an empty token was provided
158+ if [ " ${hardbreak} " -ne 0 ]; then
159+ echo " "
160+ fi
161+ done
133162}
134163
135164# arg1: Path to file with detected boot environments, 1 per line
136- # prints: key pressed, boot environment
137- # returns: 130 on error, 0 otherwise
165+ # prints: key pressed, boot environment on successful selection
166+ # returns: 0 on successful selection, 1 if Esc was pressed, 130 if BE list is missing
138167
139168draw_be () {
140- local env selected ret header
169+ local env selected header
141170
142171 env=" ${1} "
143172
144173 zdebug " using environment file: ${env} "
145174
146- test -f " ${env} " || return 130
175+ [ -f " ${env} " ] || return 130
147176
148- header=" $( header_wrap " [ENTER] boot" " [ALT+K] kernels " \
149- " [ALT+S] snapshots " " [ALT+D] set bootfs" " [ALT+E] edit kcl " \
150- " [ALT+P] pool status " " [ALT+R] recovery shell" " [ALT+C] chroot " " [ALT+H] help" ) "
177+ header=" $( header_wrap " [ENTER] boot" " [ESC] refresh view " " " \
178+ " [ALT+E] edit kcl " " [ALT+K] kernels " " [ALT+ D] set bootfs" " [ALT+S] snapshots " " " \
179+ " [ALT+C] chroot " " [ALT+R] recovery shell" " [ALT+P] pool status " " [ALT+H] help" ) "
151180
152- selected=" $( ${FUZZYSEL} -0 --prompt " BE > " \
153- --expect=alt-k,alt-d,alt-s,alt-c,alt-r,alt-p,alt-w,alt-e \
154- --header=" ${header} " --preview-window=" up:${PREVIEW_HEIGHT} " \
155- --preview=" /libexec/zfsbootmenu-preview ${BASE} {} ${BOOTFS} " < " ${env} " ) "
156- ret=$?
181+ if ! selected=" $( ${FUZZYSEL} -0 --prompt " BE > " \
182+ --expect=alt-k,alt-d,alt-s,alt-c,alt-r,alt-p,alt-w,alt-e \
183+ --header=" ${header} " --preview-window=" up:${PREVIEW_HEIGHT} " \
184+ --preview=" /libexec/zfsbootmenu-preview ${BASE} {} ${BOOTFS} " < " ${env} " ) " ; then
185+ return 1
186+ fi
157187
158188 # shellcheck disable=SC2119
159189 selected=" $( csv_cat <<< " ${selected}" ) "
160190 echo " ${selected} "
161191 zdebug " selected: ${selected} "
162192
163- return ${ret}
193+ return 0
164194}
165195
166196# arg1: ZFS filesystem name
167197# prints: bootfs, kernel, initramfs
168198# returns: 130 on error, 0 otherwise
169199
170200draw_kernel () {
171- local benv selected ret header _kernels
201+ local benv selected header _kernels
172202
173203 benv=" ${1} "
174204 _kernels=" ${BASE} /${benv} /kernels"
@@ -177,50 +207,55 @@ draw_kernel() {
177207
178208 test -f " ${_kernels} " || return 130
179209
180- header=" $( header_wrap " [ENTER] boot" " [ALT+D] set default" " [ESC] back" " [ALT+H] help" ) "
210+ header=" $( header_wrap \
211+ " [ENTER] boot" " [ESC] back" " " " [ALT+D] set default" " [ALT+H] help" ) "
181212
182- selected=" $( HELP_SECTION=KERNEL ${FUZZYSEL} --prompt " ${benv} > " \
183- --tac --expect=alt-d --with-nth=2 --header=" ${header} " \
184- --preview-window=" up:${PREVIEW_HEIGHT} " \
185- --preview=" /libexec/zfsbootmenu-preview ${BASE} ${benv} ${BOOTFS} " < " ${_kernels} " ) "
186- ret=$?
213+ if ! selected=" $( HELP_SECTION=KERNEL ${FUZZYSEL} --prompt " ${benv} > " \
214+ --tac --expect=alt-d --with-nth=2 --header=" ${header} " \
215+ --preview-window=" up:${PREVIEW_HEIGHT} " \
216+ --preview=" /libexec/zfsbootmenu-preview \
217+ ${BASE} ${benv} ${BOOTFS} " < " ${_kernels} " ) " ; then
218+ return 1
219+ fi
187220
188221 # shellcheck disable=SC2119
189222 selected=" $( csv_cat <<< " ${selected}" ) "
190223 echo " ${selected} "
191224 zdebug " selected: ${selected} "
192225
193- return ${ret}
226+ return 0
194227}
195228
196229# arg1: ZFS filesystem name
197230# prints: selected snapshot
198231# returns: 130 on error, 0 otherwise
199232
200233draw_snapshots () {
201- local benv selected ret header
234+ local benv selected header
202235
203236 benv=" ${1} "
204237
205238 zdebug " using boot environment: ${benv} "
206239
207- header=" $( header_wrap " [ENTER] duplicate" " [ALT+X] clone and promote" \
208- " [ALT+C] clone only" " [ALT+D] show diff" " [ESC] back" " [ALT+H] help" ) "
240+ header=" $( header_wrap \
241+ " [ENTER] duplicate" " [ESC] back" " " \
242+ " [ALT+D] show diff" " [ALT+X] clone and promote" " [ALT+C] clone only" " [ALT+H] help" ) "
209243
210- selected=" $( zfs list -t snapshot -H -o name " ${benv} " |
244+ if ! selected=" $( zfs list -t snapshot -H -o name " ${benv} " |
211245 HELP_SECTION=SNAPSHOT ${FUZZYSEL} --prompt " Snapshot > " \
212246 --tac --expect=alt-x,alt-c,alt-d \
213247 --preview=" /libexec/zfsbootmenu-preview ${BASE} ${benv} ${BOOTFS} " \
214248 --preview-window=" up:${PREVIEW_HEIGHT} " \
215- --header=" ${header} " ) "
216- ret=$?
249+ --header=" ${header} " ) " ; then
250+ return 1
251+ fi
217252
218253 # shellcheck disable=SC2119
219254 selected=" $( csv_cat <<< " ${selected}" ) "
220255 echo " ${selected} "
221256 zdebug " selected: ${selected} "
222257
223- return ${ret}
258+ return 0
224259}
225260
226261# arg1: ZFS snapshot
@@ -271,25 +306,25 @@ draw_diff() {
271306# returns: 130 on error, 0 otherwise
272307
273308draw_pool_status () {
274- local selected ret header hdr_width
309+ local selected header hdr_width
275310
276311 # Wrap to half width to avoid the preview window
277312 hdr_width=" $(( ( $( tput cols ) / 2 ) - 4 )) "
278313 header=" $( wrap_width=" $hdr_width " header_wrap \
279- " [ALT+R] rewind checkpoint" " [ESC] back " " [ALT+H] help" ) "
314+ " [ESC] back " " " " [ ALT+R] rewind checkpoint" " " " [ALT+H] help" ) "
280315
281- selected=" $( zpool list -H -o name |
282- HELP_SECTION=POOL ${FUZZYSEL} --prompt " Pool > " --tac \
283- --expect=alt-r --preview=" zpool status -v {}" --header=" ${header} "
284- ) "
285- ret= $?
316+ if ! selected=" $( zpool list -H -o name |
317+ HELP_SECTION=POOL ${FUZZYSEL} --prompt " Pool > " --tac \
318+ --expect=alt-r --preview=" zpool status -v {}" --header=" ${header} " ) " ; then
319+ return 1
320+ fi
286321
287322 # shellcheck disable=SC2119
288323 selected=" $( csv_cat <<< " ${selected}" ) "
289324 echo " ${selected} "
290325 zdebug " selected: ${selected} "
291326
292- return ${ret}
327+ return 0
293328}
294329
295330# arg1: bootfs kernel initramfs
0 commit comments