-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlist-select.sh
More file actions
executable file
·96 lines (82 loc) · 3.38 KB
/
list-select.sh
File metadata and controls
executable file
·96 lines (82 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env bash
# examples/list-select.sh — Interactive single-select list using shellframe
#
# Usage: ./list-select.sh
# Returns the selected item on stdout after the TUI exits.
set -u
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/shellframe.sh"
list_select() {
local -a items=("$@")
local n=${#items[@]}
local selected=0
# ── Route TUI output to the real terminal ─────────────────────────
# When called as $(list_select ...), stdout is a pipe. Redirect to
# /dev/tty so screen/draw output reaches the terminal. The final
# result printf restores stdout so the value is captured by $().
# Use fixed fd 4 — {varname} fd allocation requires bash 4.1+.
# fd 3 is reserved by shellframe_screen_enter for persistent /dev/tty output.
exec 4>&1
exec 1>/dev/tty
# ── Cleanup ───────────────────────────────────────────────────────
local saved_stty
saved_stty=$(shellframe_raw_save)
_ls_exit() {
shellframe_raw_exit "$saved_stty"
shellframe_cursor_show
shellframe_screen_exit
}
trap '_ls_exit; exit 1' INT TERM
# ── Enter TUI ─────────────────────────────────────────────────────
shellframe_screen_enter
shellframe_raw_enter
shellframe_cursor_hide
_draw() {
shellframe_screen_clear
local i
for (( i=0; i<n; i++ )); do
if (( i == selected )); then
printf " ${SHELLFRAME_BOLD}${SHELLFRAME_GREEN}> %s${SHELLFRAME_RESET}\n" "${items[$i]}"
else
printf " ${SHELLFRAME_GRAY}%s${SHELLFRAME_RESET}\n" "${items[$i]}"
fi
done
printf "\n ${SHELLFRAME_GRAY}↑/↓ move Enter select q quit${SHELLFRAME_RESET}\n"
}
_draw
# ── Input loop ────────────────────────────────────────────────────
local key result=""
while true; do
shellframe_read_key key
if [[ "$key" == "$SHELLFRAME_KEY_UP" ]]; then
(( selected > 0 )) && (( selected-- )) || true
elif [[ "$key" == "$SHELLFRAME_KEY_DOWN" ]]; then
(( selected < n - 1 )) && (( selected++ )) || true
elif [[ "$key" == "$SHELLFRAME_KEY_ENTER" || "$key" == "$SHELLFRAME_KEY_SPACE" ]]; then
result="${items[$selected]}"
break
elif [[ "$key" == 'q' || "$key" == 'Q' || "$key" == $'\x03' ]]; then
break
fi
_draw
done
_ls_exit
trap - INT TERM
# Restore original stdout so the result is captured by $() callers
exec 1>&4
exec 4>&-
[[ -n "$result" ]] && printf '%s\n' "$result"
}
# ── Demo ──────────────────────────────────────────────────────────────────────
items=(
"apple"
"banana"
"cherry"
"date"
"elderberry"
)
chosen=$(list_select "${items[@]}")
if [[ -n "$chosen" ]]; then
printf 'You selected: %s\n' "$chosen"
else
printf 'No selection.\n'
fi