blob: c53a71fef3557491694fe97cb52b2dadae351413 (
plain) (
blame)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#!/bin/bash
# local is well supported
# shellcheck disable=3043
set -eu
# TODO: use custom-1 somehow
# pick up configuration
FUZL_PROMPT=${FUZL_PROMPT:-fuzl}
FUZL_ICON=${FUZL_ICON:-}
FUZL_CLI_ARGS=${FUZL_CLI_ARGS:-$@}
fuzl_try() {
[ "$1" == "--" ] && shift 1
if ! { stderr=$(
set +x
eval "$*" 2>&1 1>&3
); } 3>&1; then
fuzl_notification "$* failed :(" "${stderr:--}" -c error
exit 1
fi
}
export FUZL_MENU_FILTER=filter
export FUZL_MENU_PASSWORD=passw
export FUZL_MENU_MESSAGE=msg
export FUZL_MENU_INPUT=input
# Shows a menu
fuzl_menu() {
local form="$1"
shift 1
local prompt options_list maxw
# If a prompt_icon is provided, prepend it.
prompt="$FUZL_PROMPT "
[ -n "$FUZL_ICON" ] && prompt="$FUZL_ICON $FUZL_PROMPT "
options_list=$(cat)
maxw=$(echo -e "$prompt\n$options_list" | wc -L)
[ "$maxw" -lt 15 ] && maxw=15
[ "$maxw" -gt 150 ] && maxw=100
case "$form" in
"$FUZL_MENU_FILTER") # Selection menu with a list of options passed via STDIN
echo -ne "$options_list" | fuzzel -d -w "$maxw" -p "$prompt" "$@"
;;
"$FUZL_MENU_PASSWORD") # Password input menu (minimalist)
echo -n | fuzzel -d -w "$maxw" -p "$prompt" --password
;;
"$FUZL_MENU_MESSAGE") # Message box menu (no input bar)
echo -ne "$options_list" | fuzzel -d -w "$maxw" -p "$prompt" "$@"
;;
"$FUZL_MENU_INPUT") # Text input menu (no list view)
echo -n | fuzzel -d -p "$prompt" "$@" --lines 0
;;
esac
}
FUZL_NOTIFICATION_ID=
fuzl_notification() {
local summary="${1:?missing summary}"
local body="${2:?missing body}"
shift 2
FUZL_NOTIFICATION_ID=$(
fyi "$@" -p -a "${FUZL_PROMPT}" "${FUZL_PROMPT}: $summary" "$body" |
cut -d= -f2
)
}
fuzl_notification_cancel() {
fyi --close "$FUZL_NOTIFICATION_ID" || true
FUZL_NOTIFICATION_ID=
}
FUZL_LOADING_PID=
fuzl_loading() {
local summary="${1:?missing summary}"
echo -e "..." | FUZL_PROMPT="$summary" fuzl_menu $FUZL_MENU_MESSAGE &
FUZL_LOADING_PID=$!
}
fuzl_loading_cancel() {
local pgid
pgid="$(ps -o pgid= "$FUZL_LOADING_PID" || return)"
kill -- -"$pgid" || true
FUZL_LOADING_PID=
}
FUZL_ACTIONS=()
fuzl_action_reset() {
# reset actions
FUZL_ACTIONS=()
}
fuzl_action_add() {
local action="${1:?}" icon="${2:?}"
shift 2
# prevent multiple occurences
printf '%s\n' "${FUZL_ACTIONS[@]}" | grep -q "^$action" && return
FUZL_ACTIONS+=("${action}\t${icon}\t${*}")
}
fuzl_action_help() {
echo "usage: $FUZL_PROMPT [action]"
echo
for action in "${FUZL_ACTIONS[@]}"; do
echo -e " $action"
done
echo
exit 0
}
fuzl_action_menu() {
local action
# only actually ask if action wasn't provided on cli
action=${FUZL_CLI_ARGS}
if [[ "$action" == "--help" ]]; then
fuzl_action_help
fi
if test -z "$action"; then
action=$(printf '%s\n' "${FUZL_ACTIONS[@]}" |
FUZL_PROMPT="$FUZL_PROMPT: $*" fuzl_menu $FUZL_MENU_FILTER --with-nth='{2} {3..}' --accept-nth=1)
fi
fuzl_action_reset
if declare -f "${FUZL_PROMPT}_${action}" >/dev/null; then
eval "${FUZL_PROMPT}_${action}" "'$*'"
else
return 1
fi
}
# setup common debug helper
[ -z "${DEBUG:-}" ] || set -x
|