fix(tui-install): paginate ui_checklist so long lists fit the screen
The applications menu (~80 entries) overflowed the terminal. Render the checklist one terminal-height page at a time, clearing and homing the cursor each round for a stable scrollable view, with n/p paging. Item numbering stays global so any entry can be toggled from any page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>main
parent
1354dc4fd1
commit
cb88b315a9
|
|
@ -126,28 +126,53 @@ ui_menu() {
|
|||
|
||||
ui_checklist() {
|
||||
# Multi-select list. Args: title prompt tag1 desc1 state1 tag2 desc2 state2 …
|
||||
# state is "on"/"off" for the initial selection. The list is redrawn each
|
||||
# round; the user toggles items by entering numbers and/or ranges
|
||||
# (e.g. "1 3 5-8"), then presses Enter to confirm. Entering 'q' aborts
|
||||
# (returns 1). The space-separated selected tags are printed to stdout.
|
||||
# state is "on"/"off" for the initial selection. Long lists are paginated to
|
||||
# the terminal height so they never scroll off-screen: the screen is cleared
|
||||
# and redrawn each round, with n/p moving between pages. The user toggles
|
||||
# items by number and/or range (e.g. "1 3 5-8") — numbering is global, so any
|
||||
# item can be toggled from any page — then presses Enter to confirm. Entering
|
||||
# 'q' aborts (returns 1). The space-separated selected tags go to stdout.
|
||||
local title="$1" prompt="$2"; shift 2
|
||||
local -a tags=() descs=() state=()
|
||||
while [[ $# -gt 0 ]]; do tags+=("$1"); descs+=("$2"); state+=("$3"); shift 3; done
|
||||
local n=${#tags[@]} i mark line tok lo hi j
|
||||
# Reserve rows for the header, prompt and footer; the remainder hold items.
|
||||
# tput may be absent on a bare TTY, so fall back to a safe 24-row assumption.
|
||||
local rows per pg=0 pages start end
|
||||
rows=$(tput lines 2>/dev/null || echo 24)
|
||||
[[ "$rows" =~ ^[0-9]+$ ]] || rows=24
|
||||
per=$(( rows - 9 )); (( per < 1 )) && per=1
|
||||
pages=$(( (n + per - 1) / per )); (( pages < 1 )) && pages=1
|
||||
while true; do
|
||||
(( pg < 0 )) && pg=0
|
||||
(( pg >= pages )) && pg=$(( pages - 1 ))
|
||||
start=$(( pg * per )); end=$(( start + per )); (( end > n )) && end=$n
|
||||
{
|
||||
# \033[2J\033[H clears the screen and homes the cursor so each page
|
||||
# paints in place rather than scrolling — a stable, scrollable view.
|
||||
printf '\033[2J\033[H'
|
||||
ui_header "$title"
|
||||
printf '%b\n\n' "$prompt"
|
||||
for i in "${!tags[@]}"; do
|
||||
printf '%b' "$prompt"
|
||||
(( pages > 1 )) && printf ' %s(page %d/%d)%s' "$C_DIM" $((pg + 1)) "$pages" "$C_RESET"
|
||||
printf '\n\n'
|
||||
for (( i = start; i < end; i++ )); do
|
||||
if [[ "${state[$i]}" == on ]]; then mark="${C_ACCENT}[x]${C_RESET}"; else mark='[ ]'; fi
|
||||
printf ' %s %s%3d%s %s\n' "$mark" "$C_ACCENT" $((i + 1)) "$C_RESET" "${descs[$i]}"
|
||||
done
|
||||
if (( pages > 1 )); then
|
||||
printf '\n%s number/range toggles (1 3 5-8) · n/p next/prev page · Enter confirms · q aborts%s\n' "$C_DIM" "$C_RESET"
|
||||
else
|
||||
printf '\n%s Toggle items by number/range (e.g. 1 3 5-8); Enter confirms, q aborts.%s\n' "$C_DIM" "$C_RESET"
|
||||
fi
|
||||
printf '%s > %s' "$C_ACCENT" "$C_RESET"
|
||||
} >&2
|
||||
read -r line </dev/tty || line=""
|
||||
[[ "$line" == q ]] && return 1
|
||||
[[ -z "$line" ]] && break
|
||||
case "$line" in
|
||||
q) return 1 ;;
|
||||
"") break ;;
|
||||
n|N) pg=$(( pg + 1 )); continue ;;
|
||||
p|P) pg=$(( pg - 1 )); continue ;;
|
||||
esac
|
||||
for tok in $line; do
|
||||
if [[ "$tok" =~ ^([0-9]+)-([0-9]+)$ ]]; then
|
||||
lo=${BASH_REMATCH[1]}; hi=${BASH_REMATCH[2]}
|
||||
|
|
|
|||
Loading…
Reference in New Issue