fpf-cli 1.6.57 → 1.6.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/bin/fpf-go-darwin-amd64 +0 -0
- package/bin/fpf-go-darwin-arm64 +0 -0
- package/bin/fpf-go-linux-amd64 +0 -0
- package/bin/fpf-go-linux-arm64 +0 -0
- package/bin/fpf-go-windows-amd64.exe +0 -0
- package/bin/fpf-go-windows-arm64.exe +0 -0
- package/fpf +75 -4227
- package/package.json +1 -2
- package/lib/fpf/manager-actions.sh +0 -335
package/fpf
CHANGED
|
@@ -2,11 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
resolve_script_path() {
|
|
6
|
+
local source_path="$1"
|
|
7
|
+
local source_dir=""
|
|
8
|
+
local link_target=""
|
|
9
|
+
|
|
10
|
+
while [[ -h "${source_path}" ]]; do
|
|
11
|
+
source_dir="$(cd -P "$(dirname "${source_path}")" && pwd)"
|
|
12
|
+
link_target="$(readlink "${source_path}")"
|
|
13
|
+
if [[ "${link_target}" == /* ]]; then
|
|
14
|
+
source_path="${link_target}"
|
|
15
|
+
else
|
|
16
|
+
source_path="${source_dir}/${link_target}"
|
|
17
|
+
fi
|
|
18
|
+
done
|
|
9
19
|
|
|
20
|
+
source_dir="$(cd -P "$(dirname "${source_path}")" && pwd)"
|
|
21
|
+
printf "%s/%s" "${source_dir}" "$(basename "${source_path}")"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
main() {
|
|
10
25
|
local script_path=""
|
|
11
26
|
local script_dir=""
|
|
12
27
|
local uname_s=""
|
|
@@ -17,8 +32,37 @@ try_exec_packaged_go_binary() {
|
|
|
17
32
|
|
|
18
33
|
script_path="$(resolve_script_path "${BASH_SOURCE[0]}")"
|
|
19
34
|
script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
if [[ "${FPF_SKIP_GO_BOOTSTRAP:-0}" == "1" ]]; then
|
|
36
|
+
case "${OSTYPE:-}" in
|
|
37
|
+
linux*)
|
|
38
|
+
uname_s="Linux"
|
|
39
|
+
;;
|
|
40
|
+
darwin*)
|
|
41
|
+
uname_s="Darwin"
|
|
42
|
+
;;
|
|
43
|
+
msys*|cygwin*|win32*)
|
|
44
|
+
uname_s="MINGW"
|
|
45
|
+
;;
|
|
46
|
+
*)
|
|
47
|
+
uname_s="$(uname -s 2>/dev/null || true)"
|
|
48
|
+
;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
case "${HOSTTYPE:-${MACHTYPE:-}}" in
|
|
52
|
+
*x86_64*|*amd64*)
|
|
53
|
+
uname_m="x86_64"
|
|
54
|
+
;;
|
|
55
|
+
*aarch64*|*arm64*)
|
|
56
|
+
uname_m="arm64"
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
uname_m="$(uname -m 2>/dev/null || true)"
|
|
60
|
+
;;
|
|
61
|
+
esac
|
|
62
|
+
else
|
|
63
|
+
uname_s="$(uname -s 2>/dev/null || true)"
|
|
64
|
+
uname_m="$(uname -m 2>/dev/null || true)"
|
|
65
|
+
fi
|
|
22
66
|
|
|
23
67
|
case "${uname_s}" in
|
|
24
68
|
Linux)
|
|
@@ -31,7 +75,8 @@ try_exec_packaged_go_binary() {
|
|
|
31
75
|
goos="windows"
|
|
32
76
|
;;
|
|
33
77
|
*)
|
|
34
|
-
|
|
78
|
+
printf "fpf: unsupported OS '%s'\n" "${uname_s}" >&2
|
|
79
|
+
exit 1
|
|
35
80
|
;;
|
|
36
81
|
esac
|
|
37
82
|
|
|
@@ -43,4239 +88,42 @@ try_exec_packaged_go_binary() {
|
|
|
43
88
|
goarch="arm64"
|
|
44
89
|
;;
|
|
45
90
|
*)
|
|
46
|
-
|
|
47
|
-
;;
|
|
48
|
-
esac
|
|
49
|
-
|
|
50
|
-
candidate="${script_dir}/bin/fpf-go-${goos}-${goarch}"
|
|
51
|
-
if [[ "${goos}" == "windows" ]]; then
|
|
52
|
-
candidate="${candidate}.exe"
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
if [[ -x "${candidate}" ]]; then
|
|
56
|
-
export FPF_SKIP_GO_BOOTSTRAP=1
|
|
57
|
-
export FPF_LEGACY_SCRIPT="${script_dir}/fpf"
|
|
58
|
-
export FPF_PACKAGE_JSON="${script_dir}/package.json"
|
|
59
|
-
exec "${candidate}" "$@"
|
|
60
|
-
fi
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
resolve_script_path() {
|
|
64
|
-
local source_path="$1"
|
|
65
|
-
local source_dir=""
|
|
66
|
-
local link_target=""
|
|
67
|
-
|
|
68
|
-
while [[ -h "${source_path}" ]]; do
|
|
69
|
-
source_dir="$(cd -P "$(dirname "${source_path}")" && pwd)"
|
|
70
|
-
link_target="$(readlink "${source_path}")"
|
|
71
|
-
if [[ "${link_target}" == /* ]]; then
|
|
72
|
-
source_path="${link_target}"
|
|
73
|
-
else
|
|
74
|
-
source_path="${source_dir}/${link_target}"
|
|
75
|
-
fi
|
|
76
|
-
done
|
|
77
|
-
|
|
78
|
-
source_dir="$(cd -P "$(dirname "${source_path}")" && pwd)"
|
|
79
|
-
printf "%s/%s" "${source_dir}" "$(basename "${source_path}")"
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try_exec_packaged_go_binary "$@"
|
|
83
|
-
|
|
84
|
-
SCRIPT_NAME="fpf"
|
|
85
|
-
SCRIPT_VERSION="1.6.57"
|
|
86
|
-
TMP_ROOT="${TMPDIR:-/tmp}/fpf"
|
|
87
|
-
SESSION_TMP_ROOT=""
|
|
88
|
-
HELP_FILE=""
|
|
89
|
-
KBINDS_FILE=""
|
|
90
|
-
CACHE_FORMAT_VERSION="1"
|
|
91
|
-
CACHE_ROOT=""
|
|
92
|
-
LOADING_INDICATOR_PID=""
|
|
93
|
-
LOADING_PROGRESS_DIR=""
|
|
94
|
-
|
|
95
|
-
ACTION="search"
|
|
96
|
-
MANAGER_OVERRIDE=""
|
|
97
|
-
IPC_MANAGER_OVERRIDE=""
|
|
98
|
-
IPC_FALLBACK_FILE=""
|
|
99
|
-
ASSUME_YES="0"
|
|
100
|
-
declare -a QUERY_PARTS=()
|
|
101
|
-
FPF_LIBRARIES_LOADED="0"
|
|
102
|
-
|
|
103
|
-
query_cache_flags() {
|
|
104
|
-
printf "%s" "query_limit=${FPF_QUERY_RESULT_LIMIT:-0};per_manager_limit=${FPF_QUERY_PER_MANAGER_LIMIT:-40};no_query_limit=${FPF_NO_QUERY_RESULT_LIMIT:-120};no_query_npm_limit=${FPF_NO_QUERY_NPM_LIMIT:-120}"
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
query_cache_default_enabled_for_manager() {
|
|
108
|
-
local manager="$1"
|
|
109
|
-
|
|
110
|
-
case "${manager}" in
|
|
111
|
-
apt|brew|pacman|bun)
|
|
112
|
-
return 0
|
|
113
|
-
;;
|
|
114
|
-
*)
|
|
115
|
-
return 1
|
|
116
|
-
;;
|
|
117
|
-
esac
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
query_cache_ttl_seconds_for_manager() {
|
|
121
|
-
local manager="$1"
|
|
122
|
-
local default_ttl="0"
|
|
123
|
-
local global_ttl="${FPF_QUERY_CACHE_TTL:-}"
|
|
124
|
-
local manager_ttl="0"
|
|
125
|
-
|
|
126
|
-
case "${manager}" in
|
|
127
|
-
apt)
|
|
128
|
-
default_ttl="180"
|
|
129
|
-
;;
|
|
130
|
-
brew)
|
|
131
|
-
default_ttl="120"
|
|
132
|
-
;;
|
|
133
|
-
pacman)
|
|
134
|
-
default_ttl="180"
|
|
135
|
-
;;
|
|
136
|
-
bun)
|
|
137
|
-
default_ttl="300"
|
|
91
|
+
goarch=""
|
|
138
92
|
;;
|
|
139
93
|
esac
|
|
140
94
|
|
|
141
|
-
if [[ -n "${
|
|
142
|
-
|
|
143
|
-
|
|
95
|
+
if [[ -n "${goarch}" ]]; then
|
|
96
|
+
candidate="${script_dir}/bin/fpf-go-${goos}-${goarch}"
|
|
97
|
+
if [[ "${goos}" == "windows" ]]; then
|
|
98
|
+
candidate="${candidate}.exe"
|
|
144
99
|
fi
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
bun)
|
|
149
|
-
manager_ttl="${FPF_BUN_QUERY_CACHE_TTL:-${default_ttl}}"
|
|
150
|
-
if ! [[ "${manager_ttl}" =~ ^[0-9]+$ ]]; then
|
|
151
|
-
manager_ttl="${default_ttl}"
|
|
152
|
-
fi
|
|
153
|
-
;;
|
|
154
|
-
apt)
|
|
155
|
-
manager_ttl="${FPF_APT_QUERY_CACHE_TTL:-${default_ttl}}"
|
|
156
|
-
if ! [[ "${manager_ttl}" =~ ^[0-9]+$ ]]; then
|
|
157
|
-
manager_ttl="${default_ttl}"
|
|
158
|
-
fi
|
|
159
|
-
;;
|
|
160
|
-
brew)
|
|
161
|
-
manager_ttl="${FPF_BREW_QUERY_CACHE_TTL:-${default_ttl}}"
|
|
162
|
-
if ! [[ "${manager_ttl}" =~ ^[0-9]+$ ]]; then
|
|
163
|
-
manager_ttl="${default_ttl}"
|
|
164
|
-
fi
|
|
165
|
-
;;
|
|
166
|
-
pacman)
|
|
167
|
-
manager_ttl="${FPF_PACMAN_QUERY_CACHE_TTL:-${default_ttl}}"
|
|
168
|
-
if ! [[ "${manager_ttl}" =~ ^[0-9]+$ ]]; then
|
|
169
|
-
manager_ttl="${default_ttl}"
|
|
170
|
-
fi
|
|
171
|
-
;;
|
|
172
|
-
*)
|
|
173
|
-
manager_ttl=0
|
|
174
|
-
;;
|
|
175
|
-
esac
|
|
176
|
-
|
|
177
|
-
printf "%s" "${manager_ttl}"
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
dynamic_reload_query_cache_bypass_value() {
|
|
181
|
-
local bypass_setting="${FPF_DYNAMIC_RELOAD_BYPASS_QUERY_CACHE:-1}"
|
|
182
|
-
|
|
183
|
-
bypass_setting="$(trim_whitespace "${bypass_setting}")"
|
|
184
|
-
bypass_setting="${bypass_setting,,}"
|
|
185
|
-
|
|
186
|
-
case "${bypass_setting}" in
|
|
187
|
-
1|true|yes|on)
|
|
188
|
-
printf "1"
|
|
189
|
-
;;
|
|
190
|
-
*)
|
|
191
|
-
printf "0"
|
|
192
|
-
;;
|
|
193
|
-
esac
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
log() {
|
|
197
|
-
printf "%s\n" "$*" >&2
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
loading_indicator_enabled() {
|
|
201
|
-
local indicator_setting=""
|
|
202
|
-
|
|
203
|
-
indicator_setting="$(trim_whitespace "${FPF_LOADING_INDICATOR:-1}")"
|
|
204
|
-
indicator_setting="${indicator_setting,,}"
|
|
205
|
-
|
|
206
|
-
case "${indicator_setting}" in
|
|
207
|
-
0|false|no|off)
|
|
208
|
-
return 1
|
|
209
|
-
;;
|
|
210
|
-
esac
|
|
211
|
-
|
|
212
|
-
[[ -t 2 ]]
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
loading_progress_begin() {
|
|
216
|
-
local managers=("$@")
|
|
217
|
-
local manager=""
|
|
218
|
-
local progress_file=""
|
|
219
|
-
|
|
220
|
-
loading_progress_end
|
|
221
|
-
loading_indicator_enabled || return 0
|
|
222
|
-
[[ "${#managers[@]}" -gt 0 ]] || return 0
|
|
223
|
-
|
|
224
|
-
LOADING_PROGRESS_DIR="$(mktemp -d "${SESSION_TMP_ROOT}/loading-progress.XXXXXX")"
|
|
225
|
-
for manager in "${managers[@]-}"; do
|
|
226
|
-
progress_file="${LOADING_PROGRESS_DIR}/${manager}.status"
|
|
227
|
-
printf "pending\tqueued\n" >"${progress_file}"
|
|
228
|
-
done
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
loading_progress_end() {
|
|
232
|
-
if [[ -z "${LOADING_PROGRESS_DIR}" ]]; then
|
|
233
|
-
return 0
|
|
234
|
-
fi
|
|
235
|
-
|
|
236
|
-
if [[ -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
237
|
-
rm -rf "${LOADING_PROGRESS_DIR}" >/dev/null 2>&1 || true
|
|
238
|
-
fi
|
|
239
|
-
|
|
240
|
-
LOADING_PROGRESS_DIR=""
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
loading_progress_mark_state() {
|
|
244
|
-
local manager="$1"
|
|
245
|
-
local state="$2"
|
|
246
|
-
local detail="${3:-}"
|
|
247
|
-
local progress_file=""
|
|
248
|
-
|
|
249
|
-
if [[ -z "${LOADING_PROGRESS_DIR}" || ! -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
250
|
-
return 0
|
|
251
|
-
fi
|
|
252
|
-
|
|
253
|
-
progress_file="${LOADING_PROGRESS_DIR}/${manager}.status"
|
|
254
|
-
printf "%s\t%s\n" "${state}" "${detail}" >"${progress_file}" 2>/dev/null || true
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
loading_progress_mark_running() {
|
|
258
|
-
local manager="$1"
|
|
259
|
-
local detail="${2:-working}"
|
|
260
|
-
loading_progress_mark_state "${manager}" "running" "${detail}"
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
loading_progress_mark_done() {
|
|
264
|
-
local manager="$1"
|
|
265
|
-
local detail="${2:-done}"
|
|
266
|
-
loading_progress_mark_state "${manager}" "done" "${detail}"
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
loading_indicator_terminal_cols() {
|
|
270
|
-
local cols="${COLUMNS:-}"
|
|
271
|
-
|
|
272
|
-
if ! [[ "${cols}" =~ ^[0-9]+$ ]] || [[ "${cols}" -lt 40 ]]; then
|
|
273
|
-
if command_exists tput; then
|
|
274
|
-
cols="$(tput cols 2>/dev/null || true)"
|
|
100
|
+
if [[ -x "${candidate}" ]]; then
|
|
101
|
+
export FPF_PACKAGE_JSON="${script_dir}/package.json"
|
|
102
|
+
exec "${candidate}" "$@"
|
|
275
103
|
fi
|
|
276
104
|
fi
|
|
277
105
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
printf "%s" "${cols}"
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
loading_indicator_fit_line() {
|
|
286
|
-
local line="$1"
|
|
287
|
-
local cols
|
|
288
|
-
local max_len
|
|
289
|
-
|
|
290
|
-
cols="$(loading_indicator_terminal_cols)"
|
|
291
|
-
max_len=$((cols - 1))
|
|
292
|
-
if [[ "${max_len}" -lt 20 ]]; then
|
|
293
|
-
max_len=20
|
|
294
|
-
fi
|
|
295
|
-
|
|
296
|
-
if [[ "${#line}" -gt "${max_len}" ]]; then
|
|
297
|
-
printf "%s..." "${line:0:$((max_len - 3))}"
|
|
298
|
-
return
|
|
299
|
-
fi
|
|
300
|
-
|
|
301
|
-
printf "%s" "${line}"
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
loading_progress_snapshot() {
|
|
305
|
-
local status_file=""
|
|
306
|
-
local manager=""
|
|
307
|
-
local status=""
|
|
308
|
-
local detail=""
|
|
309
|
-
local total=0
|
|
310
|
-
local done=0
|
|
311
|
-
local running=0
|
|
312
|
-
local queued=0
|
|
313
|
-
local progress_percent=0
|
|
314
|
-
local -a active_details=()
|
|
315
|
-
local active_text=""
|
|
316
|
-
local phase_text=""
|
|
317
|
-
local active_total=0
|
|
318
|
-
local max_active_items=3
|
|
319
|
-
local idx
|
|
320
|
-
|
|
321
|
-
if [[ -z "${LOADING_PROGRESS_DIR}" || ! -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
322
|
-
return 0
|
|
323
|
-
fi
|
|
324
|
-
|
|
325
|
-
for status_file in "${LOADING_PROGRESS_DIR}"/*.status; do
|
|
326
|
-
[[ -f "${status_file}" ]] || continue
|
|
327
|
-
total=$((total + 1))
|
|
328
|
-
manager="$(basename "${status_file}" .status)"
|
|
329
|
-
IFS=$'\t' read -r status detail <"${status_file}" || true
|
|
330
|
-
case "${status}" in
|
|
331
|
-
done)
|
|
332
|
-
done=$((done + 1))
|
|
333
|
-
;;
|
|
334
|
-
running)
|
|
335
|
-
running=$((running + 1))
|
|
336
|
-
active_total=$((active_total + 1))
|
|
337
|
-
if [[ "${#active_details[@]}" -lt "${max_active_items}" ]]; then
|
|
338
|
-
active_details+=("${manager}: ${detail:-work}")
|
|
339
|
-
fi
|
|
340
|
-
;;
|
|
341
|
-
*)
|
|
342
|
-
queued=$((queued + 1))
|
|
343
|
-
;;
|
|
344
|
-
esac
|
|
345
|
-
done
|
|
346
|
-
|
|
347
|
-
[[ "${total}" -gt 0 ]] || return 0
|
|
348
|
-
|
|
349
|
-
progress_percent=$((done * 100 / total))
|
|
350
|
-
|
|
351
|
-
if [[ "${#active_details[@]}" -gt 0 ]]; then
|
|
352
|
-
active_text=""
|
|
353
|
-
for idx in "${!active_details[@]}"; do
|
|
354
|
-
if [[ -n "${active_text}" ]]; then
|
|
355
|
-
active_text+=", "
|
|
356
|
-
fi
|
|
357
|
-
active_text+="${active_details[$idx]}"
|
|
358
|
-
done
|
|
359
|
-
if [[ "${active_total}" -gt "${#active_details[@]}" ]]; then
|
|
360
|
-
active_text+=", +$((active_total - ${#active_details[@]}))"
|
|
106
|
+
for goarch in amd64 arm64; do
|
|
107
|
+
candidate="${script_dir}/bin/fpf-go-${goos}-${goarch}"
|
|
108
|
+
if [[ "${goos}" == "windows" ]]; then
|
|
109
|
+
candidate="${candidate}.exe"
|
|
361
110
|
fi
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
else
|
|
366
|
-
phase_text="finalizing combined results"
|
|
367
|
-
fi
|
|
368
|
-
|
|
369
|
-
printf "%3s%% (%s/%s) | %s" "${progress_percent}" "${done}" "${total}" "${phase_text}"
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
start_loading_indicator() {
|
|
373
|
-
local message="${1:-Loading}"
|
|
374
|
-
|
|
375
|
-
if [[ -n "${LOADING_INDICATOR_PID}" ]]; then
|
|
376
|
-
stop_loading_indicator
|
|
377
|
-
fi
|
|
378
|
-
|
|
379
|
-
loading_indicator_enabled || return 0
|
|
380
|
-
|
|
381
|
-
(
|
|
382
|
-
trap 'exit 0' TERM INT
|
|
383
|
-
local started_epoch
|
|
384
|
-
local elapsed_seconds=0
|
|
385
|
-
local snapshot=""
|
|
386
|
-
local line_output=""
|
|
387
|
-
|
|
388
|
-
started_epoch="$(date +%s)"
|
|
389
|
-
if ! [[ "${started_epoch}" =~ ^[0-9]+$ ]]; then
|
|
390
|
-
started_epoch=0
|
|
111
|
+
if [[ -x "${candidate}" ]]; then
|
|
112
|
+
export FPF_PACKAGE_JSON="${script_dir}/package.json"
|
|
113
|
+
exec "${candidate}" "$@"
|
|
391
114
|
fi
|
|
115
|
+
done
|
|
392
116
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
snapshot="$(loading_progress_snapshot)"
|
|
400
|
-
if [[ -n "${snapshot}" ]]; then
|
|
401
|
-
line_output="${message} ${snapshot} | ${elapsed_seconds}s"
|
|
402
|
-
else
|
|
403
|
-
line_output="${message} working | ${elapsed_seconds}s"
|
|
404
|
-
fi
|
|
405
|
-
line_output="$(loading_indicator_fit_line "${line_output}")"
|
|
406
|
-
printf "\r\033[2K%s" "${line_output}" >&2
|
|
407
|
-
sleep 0.15
|
|
408
|
-
done
|
|
409
|
-
) &
|
|
410
|
-
LOADING_INDICATOR_PID="$!"
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
stop_loading_indicator() {
|
|
414
|
-
if [[ -z "${LOADING_INDICATOR_PID}" ]]; then
|
|
415
|
-
return 0
|
|
416
|
-
fi
|
|
417
|
-
|
|
418
|
-
kill "${LOADING_INDICATOR_PID}" >/dev/null 2>&1 || true
|
|
419
|
-
wait "${LOADING_INDICATOR_PID}" >/dev/null 2>&1 || true
|
|
420
|
-
LOADING_INDICATOR_PID=""
|
|
421
|
-
|
|
422
|
-
if loading_indicator_enabled; then
|
|
423
|
-
printf "\r\033[2K" >&2
|
|
424
|
-
fi
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
run_with_loading_indicator() {
|
|
428
|
-
local message="$1"
|
|
429
|
-
shift
|
|
430
|
-
|
|
431
|
-
start_loading_indicator "${message}"
|
|
432
|
-
if "$@"; then
|
|
433
|
-
stop_loading_indicator
|
|
434
|
-
return 0
|
|
117
|
+
printf "fpf: missing packaged Go binary for %s/%s\n" "${goos}" "${uname_m}" >&2
|
|
118
|
+
printf "fpf: expected one of:\n" >&2
|
|
119
|
+
printf " %s/bin/fpf-go-%s-amd64\n" "${script_dir}" "${goos}" >&2
|
|
120
|
+
printf " %s/bin/fpf-go-%s-arm64\n" "${script_dir}" "${goos}" >&2
|
|
121
|
+
if [[ "${goos}" == "windows" ]]; then
|
|
122
|
+
printf " (with .exe suffix on Windows binaries)\n" >&2
|
|
435
123
|
fi
|
|
436
|
-
|
|
437
|
-
local status="$?"
|
|
438
|
-
stop_loading_indicator
|
|
439
|
-
return "${status}"
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
die() {
|
|
443
|
-
log "Error: $*"
|
|
124
|
+
printf "fpf: run 'bash scripts/build-go-binaries.sh' to build local binaries.\n" >&2
|
|
444
125
|
exit 1
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
command_exists() {
|
|
448
|
-
command -v "$1" >/dev/null 2>&1
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
invocation_script_path() {
|
|
452
|
-
local script_path="${FPF_SELF_PATH:-${BASH_SOURCE[0]}}"
|
|
453
|
-
|
|
454
|
-
if [[ "${script_path}" != /* ]]; then
|
|
455
|
-
script_path="$(pwd)/${script_path}"
|
|
456
|
-
fi
|
|
457
|
-
|
|
458
|
-
printf "%s" "${script_path}"
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
resolve_script_dir() {
|
|
462
|
-
local script_path="${BASH_SOURCE[0]}"
|
|
463
|
-
local script_dir=""
|
|
464
|
-
|
|
465
|
-
if command_exists readlink; then
|
|
466
|
-
while [[ -L "${script_path}" ]]; do
|
|
467
|
-
script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
|
|
468
|
-
script_path="$(readlink "${script_path}")"
|
|
469
|
-
if [[ "${script_path}" != /* ]]; then
|
|
470
|
-
script_path="${script_dir}/${script_path}"
|
|
471
|
-
fi
|
|
472
|
-
done
|
|
473
|
-
fi
|
|
474
|
-
|
|
475
|
-
if [[ "${script_path}" != /* ]]; then
|
|
476
|
-
script_path="$(pwd)/${script_path}"
|
|
477
|
-
fi
|
|
478
126
|
|
|
479
|
-
script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
|
|
480
|
-
printf "%s" "${script_dir}"
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
load_fpf_libraries() {
|
|
484
|
-
local script_dir=""
|
|
485
|
-
local manager_actions_lib=""
|
|
486
|
-
|
|
487
|
-
if [[ "${FPF_LIBRARIES_LOADED}" == "1" ]]; then
|
|
488
|
-
return
|
|
489
|
-
fi
|
|
490
|
-
|
|
491
|
-
script_dir="$(resolve_script_dir)"
|
|
492
|
-
manager_actions_lib="${script_dir}/lib/fpf/manager-actions.sh"
|
|
493
|
-
|
|
494
|
-
if [[ ! -r "${manager_actions_lib}" ]]; then
|
|
495
|
-
die "Required library file not found: ${manager_actions_lib}"
|
|
496
|
-
fi
|
|
497
|
-
|
|
498
|
-
# shellcheck disable=SC1090
|
|
499
|
-
source "${manager_actions_lib}"
|
|
500
|
-
FPF_LIBRARIES_LOADED="1"
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
fzf_command_available() {
|
|
504
|
-
if [[ "${FPF_TEST_FORCE_FZF_MISSING:-0}" == "1" ]]; then
|
|
505
|
-
if [[ -n "${FPF_TEST_MOCK_BIN:-}" && -x "${FPF_TEST_MOCK_BIN}/fzf" ]]; then
|
|
506
|
-
return 0
|
|
507
|
-
fi
|
|
508
|
-
return 1
|
|
509
|
-
fi
|
|
510
|
-
|
|
511
|
-
command_exists fzf
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
assume_yes_enabled() {
|
|
515
|
-
local env_assume_yes=""
|
|
516
|
-
|
|
517
|
-
if [[ "${ASSUME_YES}" == "1" ]]; then
|
|
518
|
-
return 0
|
|
519
|
-
fi
|
|
520
|
-
|
|
521
|
-
env_assume_yes="$(trim_whitespace "${FPF_ASSUME_YES:-0}")"
|
|
522
|
-
env_assume_yes="${env_assume_yes,,}"
|
|
523
|
-
|
|
524
|
-
case "${env_assume_yes}" in
|
|
525
|
-
1|true|yes|on)
|
|
526
|
-
return 0
|
|
527
|
-
;;
|
|
528
|
-
*)
|
|
529
|
-
return 1
|
|
530
|
-
;;
|
|
531
|
-
esac
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
ensure_tmp_root() {
|
|
535
|
-
mkdir -p "${TMP_ROOT}"
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
resolve_cache_root() {
|
|
539
|
-
local os
|
|
540
|
-
os="$(uname -s)"
|
|
541
|
-
|
|
542
|
-
if [[ -n "${FPF_CACHE_DIR:-}" ]]; then
|
|
543
|
-
printf "%s" "${FPF_CACHE_DIR}"
|
|
544
|
-
return
|
|
545
|
-
fi
|
|
546
|
-
|
|
547
|
-
case "${os}" in
|
|
548
|
-
Darwin)
|
|
549
|
-
printf "%s" "${HOME}/Library/Caches/fpf"
|
|
550
|
-
;;
|
|
551
|
-
Linux)
|
|
552
|
-
if [[ -n "${XDG_CACHE_HOME:-}" ]]; then
|
|
553
|
-
printf "%s" "${XDG_CACHE_HOME}/fpf"
|
|
554
|
-
else
|
|
555
|
-
printf "%s" "${HOME}/.cache/fpf"
|
|
556
|
-
fi
|
|
557
|
-
;;
|
|
558
|
-
MINGW*|MSYS*|CYGWIN*|Windows_NT)
|
|
559
|
-
if [[ -n "${LOCALAPPDATA:-}" ]]; then
|
|
560
|
-
printf "%s" "${LOCALAPPDATA}/fpf"
|
|
561
|
-
elif [[ -n "${APPDATA:-}" ]]; then
|
|
562
|
-
printf "%s" "${APPDATA}/fpf"
|
|
563
|
-
else
|
|
564
|
-
printf "%s" "${HOME}/.cache/fpf"
|
|
565
|
-
fi
|
|
566
|
-
;;
|
|
567
|
-
*)
|
|
568
|
-
printf "%s" "${HOME}/.cache/fpf"
|
|
569
|
-
;;
|
|
570
|
-
esac
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
initialize_cache_root() {
|
|
574
|
-
if [[ -n "${CACHE_ROOT}" ]]; then
|
|
575
|
-
return
|
|
576
|
-
fi
|
|
577
|
-
|
|
578
|
-
CACHE_ROOT="$(resolve_cache_root)"
|
|
579
|
-
mkdir -p "${CACHE_ROOT}"
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
normalize_cache_query() {
|
|
583
|
-
local value="$1"
|
|
584
|
-
local -a tokens=()
|
|
585
|
-
|
|
586
|
-
read -r -a tokens <<<"${value}"
|
|
587
|
-
value="${tokens[*]}"
|
|
588
|
-
value="${value,,}"
|
|
589
|
-
|
|
590
|
-
printf "%s" "${value}"
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
trim_whitespace() {
|
|
594
|
-
local value="$1"
|
|
595
|
-
value="${value#"${value%%[![:space:]]*}"}"
|
|
596
|
-
value="${value%"${value##*[![:space:]]}"}"
|
|
597
|
-
printf "%s" "${value}"
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
selection_debug_enabled() {
|
|
601
|
-
case "${FPF_DEBUG_SELECTION:-0}" in
|
|
602
|
-
1|true|yes|on)
|
|
603
|
-
return 0
|
|
604
|
-
;;
|
|
605
|
-
*)
|
|
606
|
-
return 1
|
|
607
|
-
;;
|
|
608
|
-
esac
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
log_selection_parse_skip() {
|
|
612
|
-
local line_number="$1"
|
|
613
|
-
local reason="$2"
|
|
614
|
-
local raw_line="$3"
|
|
615
|
-
local raw_repr=""
|
|
616
|
-
|
|
617
|
-
selection_debug_enabled || return 0
|
|
618
|
-
|
|
619
|
-
printf -v raw_repr "%q" "${raw_line}"
|
|
620
|
-
log "Debug(selection): skipped line ${line_number}: ${reason}; raw=${raw_repr}"
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
platform_cache_token() {
|
|
624
|
-
local os
|
|
625
|
-
|
|
626
|
-
os="$(uname -s)"
|
|
627
|
-
printf "%s" "${os,,}"
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
cache_fingerprint() {
|
|
631
|
-
local manager="$1"
|
|
632
|
-
local query="$2"
|
|
633
|
-
local flags="$3"
|
|
634
|
-
local normalized_query
|
|
635
|
-
|
|
636
|
-
normalized_query="$(normalize_cache_query "${query}")"
|
|
637
|
-
printf "%s|%s|%s|%s|%s" "${CACHE_FORMAT_VERSION}" "${manager}" "$(platform_cache_token)" "${normalized_query}" "${flags}"
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
cache_cksum() {
|
|
641
|
-
local input="$1"
|
|
642
|
-
printf "%s" "${input}" | cksum | awk '{ print $1 }'
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
cache_catalog_key() {
|
|
646
|
-
local manager="$1"
|
|
647
|
-
printf "catalog/%s.tsv" "${manager}"
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
catalog_fixture_checksum() {
|
|
651
|
-
local fixture_name="$1"
|
|
652
|
-
local fixture_path=""
|
|
653
|
-
|
|
654
|
-
if [[ "${FPF_TEST_FIXTURES:-0}" != "1" ]]; then
|
|
655
|
-
return 1
|
|
656
|
-
fi
|
|
657
|
-
|
|
658
|
-
if [[ -z "${FPF_TEST_FIXTURE_DIR:-}" ]]; then
|
|
659
|
-
return 1
|
|
660
|
-
fi
|
|
661
|
-
|
|
662
|
-
fixture_path="${FPF_TEST_FIXTURE_DIR}/${fixture_name}"
|
|
663
|
-
[[ -r "${fixture_path}" ]] || return 1
|
|
664
|
-
cksum "${fixture_path}" | awk '{ print $1 }'
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
apt_catalog_state_token() {
|
|
668
|
-
local fixture_checksum=""
|
|
669
|
-
local lists_dir="/var/lib/apt/lists"
|
|
670
|
-
local listing=""
|
|
671
|
-
local listing_checksum=""
|
|
672
|
-
local policy_checksum=""
|
|
673
|
-
|
|
674
|
-
fixture_checksum="$(catalog_fixture_checksum "apt-dumpavail.txt" 2>/dev/null || true)"
|
|
675
|
-
if [[ -n "${fixture_checksum}" ]]; then
|
|
676
|
-
printf "fixture=%s" "${fixture_checksum}"
|
|
677
|
-
return
|
|
678
|
-
fi
|
|
679
|
-
|
|
680
|
-
if [[ -d "${lists_dir}" ]]; then
|
|
681
|
-
listing="$(find "${lists_dir}" -maxdepth 1 -type f \( -name '*_Packages' -o -name '*_Sources' -o -name '*InRelease' -o -name '*Release' \) -printf '%f|%s|%T@\n' 2>/dev/null | LC_ALL=C sort || true)"
|
|
682
|
-
if [[ -n "${listing}" ]]; then
|
|
683
|
-
listing_checksum="$(printf "%s" "${listing}" | cksum | awk '{ print $1 }')"
|
|
684
|
-
printf "lists=%s" "${listing_checksum}"
|
|
685
|
-
return
|
|
686
|
-
fi
|
|
687
|
-
fi
|
|
688
|
-
|
|
689
|
-
if command_exists apt-cache; then
|
|
690
|
-
policy_checksum="$(apt-cache policy 2>/dev/null | cksum | awk '{ print $1 }' || true)"
|
|
691
|
-
if [[ -n "${policy_checksum}" ]]; then
|
|
692
|
-
printf "policy=%s" "${policy_checksum}"
|
|
693
|
-
return
|
|
694
|
-
fi
|
|
695
|
-
fi
|
|
696
|
-
|
|
697
|
-
printf "state=unknown"
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
brew_catalog_state_token() {
|
|
701
|
-
local formula_fixture_checksum=""
|
|
702
|
-
local cask_fixture_checksum=""
|
|
703
|
-
local formula_repo=""
|
|
704
|
-
local cask_repo=""
|
|
705
|
-
local formula_head=""
|
|
706
|
-
local cask_head=""
|
|
707
|
-
local brew_version=""
|
|
708
|
-
|
|
709
|
-
formula_fixture_checksum="$(catalog_fixture_checksum "brew-formulae.txt" 2>/dev/null || true)"
|
|
710
|
-
cask_fixture_checksum="$(catalog_fixture_checksum "brew-casks.txt" 2>/dev/null || true)"
|
|
711
|
-
if [[ -n "${formula_fixture_checksum}" || -n "${cask_fixture_checksum}" ]]; then
|
|
712
|
-
printf "fixture=formula=%s;cask=%s" "${formula_fixture_checksum:-missing}" "${cask_fixture_checksum:-missing}"
|
|
713
|
-
return
|
|
714
|
-
fi
|
|
715
|
-
|
|
716
|
-
if command_exists brew; then
|
|
717
|
-
formula_repo="$(brew --repository 2>/dev/null || true)"
|
|
718
|
-
cask_repo="$(brew --repository homebrew/cask 2>/dev/null || true)"
|
|
719
|
-
fi
|
|
720
|
-
|
|
721
|
-
if command_exists git; then
|
|
722
|
-
if [[ -n "${formula_repo}" && -d "${formula_repo}/.git" ]]; then
|
|
723
|
-
formula_head="$(git -C "${formula_repo}" rev-parse HEAD 2>/dev/null || true)"
|
|
724
|
-
fi
|
|
725
|
-
if [[ -n "${cask_repo}" && -d "${cask_repo}/.git" ]]; then
|
|
726
|
-
cask_head="$(git -C "${cask_repo}" rev-parse HEAD 2>/dev/null || true)"
|
|
727
|
-
fi
|
|
728
|
-
fi
|
|
729
|
-
|
|
730
|
-
if [[ -n "${formula_head}" || -n "${cask_head}" ]]; then
|
|
731
|
-
printf "repos=formula:%s;cask:%s" "${formula_head:-missing}" "${cask_head:-missing}"
|
|
732
|
-
return
|
|
733
|
-
fi
|
|
734
|
-
|
|
735
|
-
if [[ -n "${formula_repo}" || -n "${cask_repo}" ]]; then
|
|
736
|
-
printf "repo-paths=formula:%s;cask:%s" "${formula_repo:-missing}" "${cask_repo:-missing}"
|
|
737
|
-
return
|
|
738
|
-
fi
|
|
739
|
-
|
|
740
|
-
if command_exists brew; then
|
|
741
|
-
brew_version="$(brew --version 2>/dev/null | awk 'NR == 1 { print $0; exit }' || true)"
|
|
742
|
-
if [[ -n "${brew_version}" ]]; then
|
|
743
|
-
printf "version=%s" "${brew_version}"
|
|
744
|
-
return
|
|
745
|
-
fi
|
|
746
|
-
fi
|
|
747
|
-
|
|
748
|
-
printf "state=unknown"
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
brew_catalog_state_cache_ttl_seconds() {
|
|
752
|
-
local ttl="${FPF_BREW_CATALOG_STATE_TTL:-300}"
|
|
753
|
-
|
|
754
|
-
if ! [[ "${ttl}" =~ ^[0-9]+$ ]]; then
|
|
755
|
-
ttl=300
|
|
756
|
-
fi
|
|
757
|
-
|
|
758
|
-
printf "%s" "${ttl}"
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
brew_catalog_state_cache_scope_hash() {
|
|
762
|
-
local scope_token
|
|
763
|
-
|
|
764
|
-
scope_token="fixtures=${FPF_TEST_FIXTURES:-0};fixture_dir=${FPF_TEST_FIXTURE_DIR:-}"
|
|
765
|
-
cache_cksum "${scope_token}"
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
cache_search_catalog_fingerprint_uncached() {
|
|
769
|
-
local manager="$1"
|
|
770
|
-
local command_path=""
|
|
771
|
-
local state_token="state=unknown"
|
|
772
|
-
|
|
773
|
-
case "${manager}" in
|
|
774
|
-
apt)
|
|
775
|
-
command_path="$(command -v apt-cache 2>/dev/null || printf "missing")"
|
|
776
|
-
state_token="$(apt_catalog_state_token)"
|
|
777
|
-
;;
|
|
778
|
-
brew)
|
|
779
|
-
command_path="$(command -v brew 2>/dev/null || printf "missing")"
|
|
780
|
-
state_token="$(brew_catalog_state_token)"
|
|
781
|
-
;;
|
|
782
|
-
*)
|
|
783
|
-
command_path="n/a"
|
|
784
|
-
;;
|
|
785
|
-
esac
|
|
786
|
-
|
|
787
|
-
printf "%s|cmd=%s|%s" "$(cache_fingerprint "${manager}" "" "search-catalog")" "${command_path}" "${state_token}"
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
cache_search_catalog_fingerprint() {
|
|
791
|
-
local manager="$1"
|
|
792
|
-
local state_cache_key=""
|
|
793
|
-
local state_cache_file=""
|
|
794
|
-
local state_cache_ttl=0
|
|
795
|
-
local state_cache_tmp=""
|
|
796
|
-
local state_cache_scope_hash=""
|
|
797
|
-
|
|
798
|
-
if [[ "${manager}" != "brew" ]]; then
|
|
799
|
-
cache_search_catalog_fingerprint_uncached "${manager}"
|
|
800
|
-
return
|
|
801
|
-
fi
|
|
802
|
-
|
|
803
|
-
initialize_cache_root
|
|
804
|
-
|
|
805
|
-
state_cache_scope_hash="$(brew_catalog_state_cache_scope_hash)"
|
|
806
|
-
state_cache_key="state/search-catalog-fingerprint/${manager}.${state_cache_scope_hash}.txt"
|
|
807
|
-
state_cache_file="$(cache_path_for_key "${state_cache_key}")"
|
|
808
|
-
state_cache_ttl="$(brew_catalog_state_cache_ttl_seconds)"
|
|
809
|
-
|
|
810
|
-
if [[ "${state_cache_ttl}" -gt 0 && -s "${state_cache_file}" ]] && cache_is_fresh_with_ttl "${state_cache_key}" "${state_cache_ttl}"; then
|
|
811
|
-
cat "${state_cache_file}"
|
|
812
|
-
return
|
|
813
|
-
fi
|
|
814
|
-
|
|
815
|
-
state_cache_tmp="$(mktemp "${SESSION_TMP_ROOT}/search-catalog-fingerprint.XXXXXX")"
|
|
816
|
-
cache_search_catalog_fingerprint_uncached "${manager}" >"${state_cache_tmp}" || true
|
|
817
|
-
|
|
818
|
-
if [[ -s "${state_cache_tmp}" ]]; then
|
|
819
|
-
cache_store_key_from_file "${state_cache_key}" "${manager}" "${state_cache_tmp}"
|
|
820
|
-
cat "${state_cache_tmp}"
|
|
821
|
-
fi
|
|
822
|
-
|
|
823
|
-
rm -f "${state_cache_tmp}"
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
cache_search_catalog_key() {
|
|
827
|
-
local manager="$1"
|
|
828
|
-
local fingerprint="$2"
|
|
829
|
-
local checksum
|
|
830
|
-
|
|
831
|
-
checksum="$(cache_cksum "${fingerprint}")"
|
|
832
|
-
printf "search-catalog/%s/%s.tsv" "${manager}" "${checksum}"
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
cache_query_key() {
|
|
836
|
-
local manager="$1"
|
|
837
|
-
local query="$2"
|
|
838
|
-
local flags="$3"
|
|
839
|
-
local fingerprint
|
|
840
|
-
local checksum
|
|
841
|
-
|
|
842
|
-
fingerprint="$(cache_fingerprint "${manager}" "${query}" "${flags}")"
|
|
843
|
-
checksum="$(cache_cksum "${fingerprint}")"
|
|
844
|
-
printf "query/%s/%s.tsv" "${manager}" "${checksum}"
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
cache_meta_key() {
|
|
848
|
-
local key="$1"
|
|
849
|
-
printf "meta/%s.meta" "${key}"
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
cache_path_for_key() {
|
|
853
|
-
local key="$1"
|
|
854
|
-
printf "%s/%s" "${CACHE_ROOT}" "${key}"
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
cache_atomic_write_from_file() {
|
|
858
|
-
local source_file="$1"
|
|
859
|
-
local destination_file="$2"
|
|
860
|
-
local destination_dir
|
|
861
|
-
local destination_base
|
|
862
|
-
local temp_file
|
|
863
|
-
|
|
864
|
-
destination_dir="$(dirname "${destination_file}")"
|
|
865
|
-
destination_base="$(basename "${destination_file}")"
|
|
866
|
-
|
|
867
|
-
mkdir -p "${destination_dir}"
|
|
868
|
-
temp_file="$(mktemp "${destination_dir}/.${destination_base}.tmp.XXXXXX")"
|
|
869
|
-
cp "${source_file}" "${temp_file}"
|
|
870
|
-
mv "${temp_file}" "${destination_file}"
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
cache_write_meta() {
|
|
874
|
-
local key="$1"
|
|
875
|
-
local fingerprint="$2"
|
|
876
|
-
local item_count="$3"
|
|
877
|
-
local refresh_status="${4:-}"
|
|
878
|
-
local generation="${5:-}"
|
|
879
|
-
local last_error_at="${6:-}"
|
|
880
|
-
local last_error="${7:-}"
|
|
881
|
-
local created_at
|
|
882
|
-
local created_epoch
|
|
883
|
-
local meta_key
|
|
884
|
-
local meta_file
|
|
885
|
-
local temp_meta
|
|
886
|
-
|
|
887
|
-
created_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
888
|
-
created_epoch="$(date +%s)"
|
|
889
|
-
meta_key="$(cache_meta_key "${key}")"
|
|
890
|
-
meta_file="$(cache_path_for_key "${meta_key}")"
|
|
891
|
-
temp_meta="$(mktemp "${SESSION_TMP_ROOT}/meta.XXXXXX")"
|
|
892
|
-
|
|
893
|
-
{
|
|
894
|
-
printf "format_version=%s\n" "${CACHE_FORMAT_VERSION}"
|
|
895
|
-
printf "created_at=%s\n" "${created_at}"
|
|
896
|
-
printf "created_epoch=%s\n" "${created_epoch}"
|
|
897
|
-
printf "fingerprint=%s\n" "${fingerprint}"
|
|
898
|
-
printf "item_count=%s\n" "${item_count}"
|
|
899
|
-
if [[ -n "${refresh_status}" ]]; then
|
|
900
|
-
printf "refresh_status=%s\n" "${refresh_status}"
|
|
901
|
-
fi
|
|
902
|
-
if [[ -n "${generation}" ]]; then
|
|
903
|
-
printf "generation=%s\n" "${generation}"
|
|
904
|
-
fi
|
|
905
|
-
if [[ -n "${last_error_at}" ]]; then
|
|
906
|
-
printf "last_error_at=%s\n" "${last_error_at}"
|
|
907
|
-
fi
|
|
908
|
-
if [[ -n "${last_error}" ]]; then
|
|
909
|
-
printf "last_error=%s\n" "${last_error}"
|
|
910
|
-
fi
|
|
911
|
-
} >"${temp_meta}"
|
|
912
|
-
|
|
913
|
-
cache_atomic_write_from_file "${temp_meta}" "${meta_file}"
|
|
914
|
-
rm -f "${temp_meta}"
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
cache_store_key_from_file() {
|
|
918
|
-
local key="$1"
|
|
919
|
-
local fingerprint="$2"
|
|
920
|
-
local source_file="$3"
|
|
921
|
-
local refresh_status="${4:-}"
|
|
922
|
-
local generation="${5:-}"
|
|
923
|
-
local last_error_at="${6:-}"
|
|
924
|
-
local last_error="${7:-}"
|
|
925
|
-
local cache_file
|
|
926
|
-
local item_count
|
|
927
|
-
|
|
928
|
-
cache_file="$(cache_path_for_key "${key}")"
|
|
929
|
-
item_count="$(awk 'END { print NR + 0 }' "${source_file}")"
|
|
930
|
-
|
|
931
|
-
cache_atomic_write_from_file "${source_file}" "${cache_file}"
|
|
932
|
-
cache_write_meta "${key}" "${fingerprint}" "${item_count}" "${refresh_status}" "${generation}" "${last_error_at}" "${last_error}"
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
cache_meta_value_for_key() {
|
|
936
|
-
local key="$1"
|
|
937
|
-
local field_name="$2"
|
|
938
|
-
local meta_file
|
|
939
|
-
|
|
940
|
-
meta_file="$(cache_path_for_key "$(cache_meta_key "${key}")")"
|
|
941
|
-
if [[ ! -r "${meta_file}" ]]; then
|
|
942
|
-
return 1
|
|
943
|
-
fi
|
|
944
|
-
|
|
945
|
-
awk -F'=' -v key="${field_name}" '$1 == key { value=substr($0, index($0, "=") + 1); print value; exit }' "${meta_file}"
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
cache_is_fresh_with_ttl() {
|
|
949
|
-
local key="$1"
|
|
950
|
-
local ttl_seconds="$2"
|
|
951
|
-
local created_epoch
|
|
952
|
-
local now_epoch
|
|
953
|
-
local age_seconds
|
|
954
|
-
|
|
955
|
-
if ! [[ "${ttl_seconds}" =~ ^[0-9]+$ ]]; then
|
|
956
|
-
return 1
|
|
957
|
-
fi
|
|
958
|
-
|
|
959
|
-
if [[ "${ttl_seconds}" -eq 0 ]]; then
|
|
960
|
-
return 1
|
|
961
|
-
fi
|
|
962
|
-
|
|
963
|
-
created_epoch="$(cache_meta_value_for_key "${key}" "created_epoch" 2>/dev/null || true)"
|
|
964
|
-
if ! [[ "${created_epoch}" =~ ^[0-9]+$ ]]; then
|
|
965
|
-
return 1
|
|
966
|
-
fi
|
|
967
|
-
|
|
968
|
-
now_epoch="$(date +%s)"
|
|
969
|
-
if ! [[ "${now_epoch}" =~ ^[0-9]+$ ]]; then
|
|
970
|
-
return 1
|
|
971
|
-
fi
|
|
972
|
-
|
|
973
|
-
age_seconds=$((now_epoch - created_epoch))
|
|
974
|
-
if [[ "${age_seconds}" -lt 0 ]]; then
|
|
975
|
-
return 1
|
|
976
|
-
fi
|
|
977
|
-
|
|
978
|
-
[[ "${age_seconds}" -lt "${ttl_seconds}" ]]
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
cache_emit_query_rows_if_valid() {
|
|
982
|
-
local cache_file="$1"
|
|
983
|
-
|
|
984
|
-
[[ -s "${cache_file}" ]] || return 1
|
|
985
|
-
|
|
986
|
-
if ! awk -F'\t' 'NF >= 2 && $1 != "" { next } { exit 1 } END { if (NR == 0) exit 1 }' "${cache_file}" >/dev/null 2>&1; then
|
|
987
|
-
return 1
|
|
988
|
-
fi
|
|
989
|
-
|
|
990
|
-
awk -F'\t' 'NF >= 2 && $1 != "" { desc=$2; if (desc == "") desc="-"; print $1 "\t" desc }' "${cache_file}"
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
bun_generation_state_key() {
|
|
994
|
-
local key="$1"
|
|
995
|
-
printf "state/%s.generation" "${key}"
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
bun_generation_read() {
|
|
999
|
-
local key="$1"
|
|
1000
|
-
local state_file
|
|
1001
|
-
local current="0"
|
|
1002
|
-
|
|
1003
|
-
state_file="$(cache_path_for_key "$(bun_generation_state_key "${key}")")"
|
|
1004
|
-
if [[ -r "${state_file}" ]]; then
|
|
1005
|
-
current="$(awk 'NR == 1 { print $1; exit }' "${state_file}")"
|
|
1006
|
-
fi
|
|
1007
|
-
|
|
1008
|
-
if ! [[ "${current}" =~ ^[0-9]+$ ]]; then
|
|
1009
|
-
current="0"
|
|
1010
|
-
fi
|
|
1011
|
-
|
|
1012
|
-
printf "%s" "${current}"
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
bun_generation_write() {
|
|
1016
|
-
local key="$1"
|
|
1017
|
-
local generation="$2"
|
|
1018
|
-
local state_key
|
|
1019
|
-
local state_file
|
|
1020
|
-
local temp_file
|
|
1021
|
-
|
|
1022
|
-
state_key="$(bun_generation_state_key "${key}")"
|
|
1023
|
-
state_file="$(cache_path_for_key "${state_key}")"
|
|
1024
|
-
temp_file="$(mktemp "${SESSION_TMP_ROOT}/bun-generation.XXXXXX")"
|
|
1025
|
-
printf "%s\n" "${generation}" >"${temp_file}"
|
|
1026
|
-
cache_atomic_write_from_file "${temp_file}" "${state_file}"
|
|
1027
|
-
rm -f "${temp_file}"
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
bun_generation_next() {
|
|
1031
|
-
local key="$1"
|
|
1032
|
-
local current
|
|
1033
|
-
local next
|
|
1034
|
-
|
|
1035
|
-
current="$(bun_generation_read "${key}")"
|
|
1036
|
-
next=$((current + 1))
|
|
1037
|
-
bun_generation_write "${key}" "${next}"
|
|
1038
|
-
printf "%s" "${next}"
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
bun_refresh_idle_seconds() {
|
|
1042
|
-
local idle_seconds="${FPF_BUN_REFRESH_IDLE:-0.12}"
|
|
1043
|
-
if ! [[ "${idle_seconds}" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
1044
|
-
idle_seconds="0.12"
|
|
1045
|
-
fi
|
|
1046
|
-
printf "%s" "${idle_seconds}"
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
bun_emit_refresh_failure_meta() {
|
|
1050
|
-
local key="$1"
|
|
1051
|
-
local fingerprint="$2"
|
|
1052
|
-
local generation="$3"
|
|
1053
|
-
local last_error="$4"
|
|
1054
|
-
local cache_file
|
|
1055
|
-
local item_count="0"
|
|
1056
|
-
local last_error_at
|
|
1057
|
-
|
|
1058
|
-
cache_file="$(cache_path_for_key "${key}")"
|
|
1059
|
-
if [[ -s "${cache_file}" ]]; then
|
|
1060
|
-
item_count="$(awk 'END { print NR + 0 }' "${cache_file}")"
|
|
1061
|
-
fi
|
|
1062
|
-
|
|
1063
|
-
last_error_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
1064
|
-
cache_write_meta "${key}" "${fingerprint}" "${item_count}" "error" "${generation}" "${last_error_at}" "${last_error}"
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
bun_try_hot_reload_after_refresh() {
|
|
1068
|
-
local query="$1"
|
|
1069
|
-
|
|
1070
|
-
if [[ -n "${FPF_BUN_REFRESH_MANAGER_OVERRIDE:-}" || -n "${FPF_BUN_REFRESH_FALLBACK_FILE:-}" ]]; then
|
|
1071
|
-
FPF_BUN_SKIP_REFRESH_SCHEDULE=1 \
|
|
1072
|
-
FPF_IPC_MANAGER_OVERRIDE="${FPF_BUN_REFRESH_MANAGER_OVERRIDE:-}" \
|
|
1073
|
-
FPF_IPC_FALLBACK_FILE="${FPF_BUN_REFRESH_FALLBACK_FILE:-}" \
|
|
1074
|
-
run_ipc_reload_action "${query}" || true
|
|
1075
|
-
fi
|
|
1076
|
-
|
|
1077
|
-
if [[ -n "${FPF_TEST_CACHE_REFRESH_SIGNAL_FILE:-}" ]] && command_exists fpf-refresh-signal; then
|
|
1078
|
-
fpf-refresh-signal >/dev/null 2>&1 || true
|
|
1079
|
-
fi
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
bun_run_refresh_worker() {
|
|
1083
|
-
local manager="$1"
|
|
1084
|
-
local query="$2"
|
|
1085
|
-
local flags="$3"
|
|
1086
|
-
local key="$4"
|
|
1087
|
-
local fingerprint="$5"
|
|
1088
|
-
local generation="$6"
|
|
1089
|
-
local output_tmp
|
|
1090
|
-
|
|
1091
|
-
sleep "$(bun_refresh_idle_seconds)"
|
|
1092
|
-
|
|
1093
|
-
if [[ "${generation}" != "$(bun_generation_read "${key}")" ]]; then
|
|
1094
|
-
return 0
|
|
1095
|
-
fi
|
|
1096
|
-
|
|
1097
|
-
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/bun-refresh.XXXXXX")"
|
|
1098
|
-
if ! manager_bun_search_entries_strict "${query}" >"${output_tmp}"; then
|
|
1099
|
-
rm -f "${output_tmp}"
|
|
1100
|
-
bun_emit_refresh_failure_meta "${key}" "${fingerprint}" "${generation}" "bun_search_failed"
|
|
1101
|
-
send_fzf_prompt_action "Search> " || true
|
|
1102
|
-
return 1
|
|
1103
|
-
fi
|
|
1104
|
-
|
|
1105
|
-
if [[ "${generation}" != "$(bun_generation_read "${key}")" ]]; then
|
|
1106
|
-
rm -f "${output_tmp}"
|
|
1107
|
-
return 0
|
|
1108
|
-
fi
|
|
1109
|
-
|
|
1110
|
-
cache_store_key_from_file "${key}" "${fingerprint}" "${output_tmp}" "success" "${generation}"
|
|
1111
|
-
rm -f "${output_tmp}"
|
|
1112
|
-
bun_try_hot_reload_after_refresh "${query}"
|
|
1113
|
-
return 0
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
start_bun_refresh_worker_async() {
|
|
1117
|
-
local manager="$1"
|
|
1118
|
-
local query="$2"
|
|
1119
|
-
local flags="$3"
|
|
1120
|
-
local key="$4"
|
|
1121
|
-
local fingerprint="$5"
|
|
1122
|
-
local generation="$6"
|
|
1123
|
-
local fallback_file="$7"
|
|
1124
|
-
local manager_override="$8"
|
|
1125
|
-
local script_path="${BASH_SOURCE[0]}"
|
|
1126
|
-
|
|
1127
|
-
FPF_BUN_REFRESH_FLAGS="${flags}" \
|
|
1128
|
-
FPF_BUN_REFRESH_KEY="${key}" \
|
|
1129
|
-
FPF_BUN_REFRESH_FINGERPRINT="${fingerprint}" \
|
|
1130
|
-
FPF_BUN_REFRESH_GENERATION="${generation}" \
|
|
1131
|
-
FPF_BUN_REFRESH_FALLBACK_FILE="${fallback_file}" \
|
|
1132
|
-
FPF_BUN_REFRESH_MANAGER_OVERRIDE="${manager_override}" \
|
|
1133
|
-
"${script_path}" --bun-refresh-worker --manager "${manager}" -- "${query}" >/dev/null 2>&1 &
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
build_apt_catalog_entries() {
|
|
1137
|
-
apt-cache dumpavail 2>/dev/null |
|
|
1138
|
-
awk '
|
|
1139
|
-
function flush_entry() {
|
|
1140
|
-
if (pkg == "") {
|
|
1141
|
-
return
|
|
1142
|
-
}
|
|
1143
|
-
desc_out = desc
|
|
1144
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", desc_out)
|
|
1145
|
-
if (desc_out == "") {
|
|
1146
|
-
desc_out = "-"
|
|
1147
|
-
}
|
|
1148
|
-
print pkg "\t" desc_out
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
/^Package:[[:space:]]*/ {
|
|
1152
|
-
flush_entry()
|
|
1153
|
-
pkg = $0
|
|
1154
|
-
sub(/^Package:[[:space:]]*/, "", pkg)
|
|
1155
|
-
desc = ""
|
|
1156
|
-
next
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
/^Description:[[:space:]]*/ {
|
|
1160
|
-
desc = $0
|
|
1161
|
-
sub(/^Description:[[:space:]]*/, "", desc)
|
|
1162
|
-
next
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
/^[[:space:]]+/ {
|
|
1166
|
-
if (desc != "") {
|
|
1167
|
-
line = $0
|
|
1168
|
-
sub(/^[[:space:]]+/, "", line)
|
|
1169
|
-
if (line != "") {
|
|
1170
|
-
desc = desc " " line
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
next
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
/^$/ {
|
|
1177
|
-
flush_entry()
|
|
1178
|
-
pkg = ""
|
|
1179
|
-
desc = ""
|
|
1180
|
-
next
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
END {
|
|
1184
|
-
flush_entry()
|
|
1185
|
-
}
|
|
1186
|
-
' |
|
|
1187
|
-
awk -F'\t' 'NF >= 1 && $1 != "" { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' |
|
|
1188
|
-
awk -F'\t' '!seen[$1]++'
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
build_brew_catalog_entries() {
|
|
1192
|
-
{
|
|
1193
|
-
brew formulae 2>/dev/null || true
|
|
1194
|
-
brew casks 2>/dev/null || true
|
|
1195
|
-
} |
|
|
1196
|
-
awk 'NF >= 1 && $1 != "" { print $1 "\t-" }' |
|
|
1197
|
-
awk -F'\t' '!seen[$1]++'
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
build_search_catalog_entries_for_manager() {
|
|
1201
|
-
local manager="$1"
|
|
1202
|
-
|
|
1203
|
-
case "${manager}" in
|
|
1204
|
-
apt)
|
|
1205
|
-
build_apt_catalog_entries
|
|
1206
|
-
;;
|
|
1207
|
-
brew)
|
|
1208
|
-
build_brew_catalog_entries
|
|
1209
|
-
;;
|
|
1210
|
-
*)
|
|
1211
|
-
return 1
|
|
1212
|
-
;;
|
|
1213
|
-
esac
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
search_catalog_async_prewarm_enabled() {
|
|
1217
|
-
local setting="${FPF_SEARCH_CATALOG_ASYNC_PREWARM:-1}"
|
|
1218
|
-
|
|
1219
|
-
if [[ -z "${FPF_SEARCH_CATALOG_ASYNC_PREWARM+x}" && -n "${FPF_TEST_LOG:-}" ]]; then
|
|
1220
|
-
return 1
|
|
1221
|
-
fi
|
|
1222
|
-
|
|
1223
|
-
setting="$(trim_whitespace "${setting}")"
|
|
1224
|
-
setting="${setting,,}"
|
|
1225
|
-
|
|
1226
|
-
case "${setting}" in
|
|
1227
|
-
0|false|no|off)
|
|
1228
|
-
return 1
|
|
1229
|
-
;;
|
|
1230
|
-
esac
|
|
1231
|
-
|
|
1232
|
-
case "${ACTION}" in
|
|
1233
|
-
search)
|
|
1234
|
-
return 0
|
|
1235
|
-
;;
|
|
1236
|
-
feed-search)
|
|
1237
|
-
case "${FPF_SKIP_INSTALLED_MARKERS:-0}" in
|
|
1238
|
-
1|true|yes|on)
|
|
1239
|
-
return 0
|
|
1240
|
-
;;
|
|
1241
|
-
esac
|
|
1242
|
-
;;
|
|
1243
|
-
esac
|
|
1244
|
-
|
|
1245
|
-
return 1
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
search_catalog_prewarm_lock_dir() {
|
|
1249
|
-
local manager="$1"
|
|
1250
|
-
printf "%s/state/search-catalog/%s.lock" "${CACHE_ROOT}" "${manager}"
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
run_search_catalog_prewarm_worker() {
|
|
1254
|
-
local manager="$1"
|
|
1255
|
-
local output_tmp
|
|
1256
|
-
local cache_fingerprint_value
|
|
1257
|
-
local cache_key
|
|
1258
|
-
|
|
1259
|
-
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/search-catalog-prewarm.XXXXXX")"
|
|
1260
|
-
build_search_catalog_entries_for_manager "${manager}" >"${output_tmp}" || true
|
|
1261
|
-
|
|
1262
|
-
if [[ -s "${output_tmp}" ]]; then
|
|
1263
|
-
cache_fingerprint_value="$(cache_search_catalog_fingerprint "${manager}")"
|
|
1264
|
-
cache_key="$(cache_search_catalog_key "${manager}" "${cache_fingerprint_value}")"
|
|
1265
|
-
cache_store_key_from_file "${cache_key}" "${cache_fingerprint_value}" "${output_tmp}"
|
|
1266
|
-
fi
|
|
1267
|
-
|
|
1268
|
-
rm -f "${output_tmp}"
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
start_search_catalog_prewarm_async() {
|
|
1272
|
-
local manager="$1"
|
|
1273
|
-
local lock_dir
|
|
1274
|
-
|
|
1275
|
-
search_catalog_async_prewarm_enabled || return 0
|
|
1276
|
-
case "${manager}" in
|
|
1277
|
-
apt|brew)
|
|
1278
|
-
;;
|
|
1279
|
-
*)
|
|
1280
|
-
return 0
|
|
1281
|
-
;;
|
|
1282
|
-
esac
|
|
1283
|
-
|
|
1284
|
-
initialize_cache_root
|
|
1285
|
-
lock_dir="$(search_catalog_prewarm_lock_dir "${manager}")"
|
|
1286
|
-
mkdir -p "$(dirname "${lock_dir}")"
|
|
1287
|
-
|
|
1288
|
-
if ! mkdir "${lock_dir}" 2>/dev/null; then
|
|
1289
|
-
return 0
|
|
1290
|
-
fi
|
|
1291
|
-
|
|
1292
|
-
if [[ -n "${FPF_TEST_LOG:-}" ]]; then
|
|
1293
|
-
run_search_catalog_prewarm_worker "${manager}" || true
|
|
1294
|
-
rmdir "${lock_dir}" >/dev/null 2>&1 || true
|
|
1295
|
-
return 0
|
|
1296
|
-
fi
|
|
1297
|
-
|
|
1298
|
-
(
|
|
1299
|
-
run_search_catalog_prewarm_worker "${manager}" || true
|
|
1300
|
-
rmdir "${lock_dir}" >/dev/null 2>&1 || true
|
|
1301
|
-
) >/dev/null 2>&1 &
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
ensure_search_catalog_cache() {
|
|
1305
|
-
local manager="$1"
|
|
1306
|
-
local cache_fingerprint_value
|
|
1307
|
-
local cache_key
|
|
1308
|
-
local cache_file
|
|
1309
|
-
local output_tmp
|
|
1310
|
-
|
|
1311
|
-
initialize_cache_root
|
|
1312
|
-
|
|
1313
|
-
cache_fingerprint_value="$(cache_search_catalog_fingerprint "${manager}")"
|
|
1314
|
-
cache_key="$(cache_search_catalog_key "${manager}" "${cache_fingerprint_value}")"
|
|
1315
|
-
cache_file="$(cache_path_for_key "${cache_key}")"
|
|
1316
|
-
|
|
1317
|
-
if [[ -s "${cache_file}" ]]; then
|
|
1318
|
-
return 0
|
|
1319
|
-
fi
|
|
1320
|
-
|
|
1321
|
-
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/search-catalog.XXXXXX")"
|
|
1322
|
-
|
|
1323
|
-
build_search_catalog_entries_for_manager "${manager}" >"${output_tmp}" || true
|
|
1324
|
-
|
|
1325
|
-
if [[ -s "${output_tmp}" ]]; then
|
|
1326
|
-
cache_store_key_from_file "${cache_key}" "${cache_fingerprint_value}" "${output_tmp}"
|
|
1327
|
-
rm -f "${output_tmp}"
|
|
1328
|
-
return 0
|
|
1329
|
-
fi
|
|
1330
|
-
|
|
1331
|
-
rm -f "${output_tmp}"
|
|
1332
|
-
return 1
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
search_entries_from_catalog_cache() {
|
|
1336
|
-
local manager="$1"
|
|
1337
|
-
local query="$2"
|
|
1338
|
-
local cache_fingerprint_value
|
|
1339
|
-
local cache_key
|
|
1340
|
-
local cache_file
|
|
1341
|
-
|
|
1342
|
-
initialize_cache_root
|
|
1343
|
-
|
|
1344
|
-
cache_fingerprint_value="$(cache_search_catalog_fingerprint "${manager}")"
|
|
1345
|
-
cache_key="$(cache_search_catalog_key "${manager}" "${cache_fingerprint_value}")"
|
|
1346
|
-
cache_file="$(cache_path_for_key "${cache_key}")"
|
|
1347
|
-
|
|
1348
|
-
if [[ ! -s "${cache_file}" ]]; then
|
|
1349
|
-
return 1
|
|
1350
|
-
fi
|
|
1351
|
-
|
|
1352
|
-
awk -F'\t' -v query="${query}" '
|
|
1353
|
-
BEGIN {
|
|
1354
|
-
normalized = tolower(query)
|
|
1355
|
-
token_count = split(normalized, raw_tokens, /[[:space:]]+/)
|
|
1356
|
-
token_index = 0
|
|
1357
|
-
for (i = 1; i <= token_count; i++) {
|
|
1358
|
-
if (raw_tokens[i] != "") {
|
|
1359
|
-
token_index++
|
|
1360
|
-
tokens[token_index] = raw_tokens[i]
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
{
|
|
1365
|
-
haystack = tolower($1 " " $2)
|
|
1366
|
-
matched = 1
|
|
1367
|
-
for (i = 1; i <= token_index; i++) {
|
|
1368
|
-
if (index(haystack, tokens[i]) == 0) {
|
|
1369
|
-
matched = 0
|
|
1370
|
-
break
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
if (matched) {
|
|
1374
|
-
desc = $2
|
|
1375
|
-
if (desc == "") {
|
|
1376
|
-
desc = "-"
|
|
1377
|
-
}
|
|
1378
|
-
print $1 "\t" desc
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
' "${cache_file}" || return 1
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
initialize_session_tmp_root() {
|
|
1385
|
-
if [[ -n "${SESSION_TMP_ROOT}" ]]; then
|
|
1386
|
-
return
|
|
1387
|
-
fi
|
|
1388
|
-
|
|
1389
|
-
if [[ -n "${FPF_SESSION_TMP_ROOT:-}" ]]; then
|
|
1390
|
-
SESSION_TMP_ROOT="${FPF_SESSION_TMP_ROOT}"
|
|
1391
|
-
mkdir -p "${SESSION_TMP_ROOT}"
|
|
1392
|
-
else
|
|
1393
|
-
SESSION_TMP_ROOT="$(mktemp -d "${TMP_ROOT}/session.XXXXXX")"
|
|
1394
|
-
fi
|
|
1395
|
-
HELP_FILE="${SESSION_TMP_ROOT}/help"
|
|
1396
|
-
KBINDS_FILE="${SESSION_TMP_ROOT}/keybinds"
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
run_preview_manager_output() {
|
|
1400
|
-
local manager="$1"
|
|
1401
|
-
local package="$2"
|
|
1402
|
-
|
|
1403
|
-
manager_show_info "${manager}" "${package}" || true
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
run_preview_item_action() {
|
|
1407
|
-
local manager="$1"
|
|
1408
|
-
local package="$2"
|
|
1409
|
-
local cache_dir="${SESSION_TMP_ROOT}/preview-cache"
|
|
1410
|
-
local cache_key=""
|
|
1411
|
-
local cache_file=""
|
|
1412
|
-
local temp_file=""
|
|
1413
|
-
|
|
1414
|
-
[[ -n "${manager}" && -n "${package}" ]] || return 0
|
|
1415
|
-
|
|
1416
|
-
mkdir -p "${cache_dir}"
|
|
1417
|
-
cache_key="$(cache_cksum "${manager}|${package}")"
|
|
1418
|
-
cache_file="${cache_dir}/${manager}.${cache_key}.txt"
|
|
1419
|
-
|
|
1420
|
-
if [[ -f "${cache_file}" ]]; then
|
|
1421
|
-
cat "${cache_file}"
|
|
1422
|
-
return 0
|
|
1423
|
-
fi
|
|
1424
|
-
|
|
1425
|
-
temp_file="$(mktemp "${SESSION_TMP_ROOT}/preview.XXXXXX")"
|
|
1426
|
-
run_preview_manager_output "${manager}" "${package}" >"${temp_file}"
|
|
1427
|
-
mv -f "${temp_file}" "${cache_file}"
|
|
1428
|
-
cat "${cache_file}"
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
cleanup_session_tmp_root() {
|
|
1432
|
-
stop_loading_indicator
|
|
1433
|
-
loading_progress_end
|
|
1434
|
-
|
|
1435
|
-
if [[ -n "${SESSION_TMP_ROOT}" && -d "${SESSION_TMP_ROOT}" ]]; then
|
|
1436
|
-
rm -rf "${SESSION_TMP_ROOT}"
|
|
1437
|
-
fi
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
run_as_root() {
|
|
1441
|
-
if [[ "${EUID}" -eq 0 ]]; then
|
|
1442
|
-
"$@"
|
|
1443
|
-
return
|
|
1444
|
-
fi
|
|
1445
|
-
|
|
1446
|
-
if command_exists sudo; then
|
|
1447
|
-
sudo "$@"
|
|
1448
|
-
return
|
|
1449
|
-
fi
|
|
1450
|
-
|
|
1451
|
-
die "Root privileges are required for: $*"
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
manager_list() {
|
|
1455
|
-
printf "%s\n" "apt dnf pacman zypper emerge brew winget choco scoop snap flatpak npm bun"
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
manager_supported() {
|
|
1459
|
-
local manager="$1"
|
|
1460
|
-
case "${manager}" in
|
|
1461
|
-
apt|dnf|pacman|zypper|emerge|brew|winget|choco|scoop|snap|flatpak|npm|bun)
|
|
1462
|
-
return 0
|
|
1463
|
-
;;
|
|
1464
|
-
*)
|
|
1465
|
-
return 1
|
|
1466
|
-
;;
|
|
1467
|
-
esac
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
|
-
manager_command_ready() {
|
|
1471
|
-
local manager="$1"
|
|
1472
|
-
case "${manager}" in
|
|
1473
|
-
apt)
|
|
1474
|
-
command_exists apt-cache && command_exists apt-get && command_exists dpkg-query
|
|
1475
|
-
;;
|
|
1476
|
-
dnf)
|
|
1477
|
-
command_exists dnf
|
|
1478
|
-
;;
|
|
1479
|
-
pacman)
|
|
1480
|
-
command_exists pacman
|
|
1481
|
-
;;
|
|
1482
|
-
zypper)
|
|
1483
|
-
command_exists zypper
|
|
1484
|
-
;;
|
|
1485
|
-
emerge)
|
|
1486
|
-
command_exists emerge
|
|
1487
|
-
;;
|
|
1488
|
-
brew)
|
|
1489
|
-
command_exists brew
|
|
1490
|
-
;;
|
|
1491
|
-
winget)
|
|
1492
|
-
command_exists winget
|
|
1493
|
-
;;
|
|
1494
|
-
choco)
|
|
1495
|
-
command_exists choco
|
|
1496
|
-
;;
|
|
1497
|
-
scoop)
|
|
1498
|
-
command_exists scoop
|
|
1499
|
-
;;
|
|
1500
|
-
snap)
|
|
1501
|
-
command_exists snap
|
|
1502
|
-
;;
|
|
1503
|
-
flatpak)
|
|
1504
|
-
command_exists flatpak
|
|
1505
|
-
;;
|
|
1506
|
-
npm)
|
|
1507
|
-
command_exists npm
|
|
1508
|
-
;;
|
|
1509
|
-
bun)
|
|
1510
|
-
command_exists bun
|
|
1511
|
-
;;
|
|
1512
|
-
*)
|
|
1513
|
-
return 1
|
|
1514
|
-
;;
|
|
1515
|
-
esac
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
flatpak_has_any_remotes() {
|
|
1519
|
-
if ! manager_command_ready flatpak; then
|
|
1520
|
-
return 1
|
|
1521
|
-
fi
|
|
1522
|
-
|
|
1523
|
-
if flatpak remotes --columns=name 2>/dev/null | awk 'NF > 0 { found=1; exit } END { exit (found ? 0 : 1) }'; then
|
|
1524
|
-
return 0
|
|
1525
|
-
fi
|
|
1526
|
-
|
|
1527
|
-
if flatpak remote-list --columns=name 2>/dev/null | awk 'NF > 0 { found=1; exit } END { exit (found ? 0 : 1) }'; then
|
|
1528
|
-
return 0
|
|
1529
|
-
fi
|
|
1530
|
-
|
|
1531
|
-
return 1
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
flatpak_has_flathub_remote() {
|
|
1535
|
-
if ! manager_command_ready flatpak; then
|
|
1536
|
-
return 1
|
|
1537
|
-
fi
|
|
1538
|
-
|
|
1539
|
-
if flatpak remotes --columns=name 2>/dev/null | awk '{
|
|
1540
|
-
name=tolower($1)
|
|
1541
|
-
if (name == "flathub") {
|
|
1542
|
-
found=1
|
|
1543
|
-
exit
|
|
1544
|
-
}
|
|
1545
|
-
} END { exit (found ? 0 : 1) }'; then
|
|
1546
|
-
return 0
|
|
1547
|
-
fi
|
|
1548
|
-
|
|
1549
|
-
if flatpak remote-list --columns=name 2>/dev/null | awk '{
|
|
1550
|
-
name=tolower($1)
|
|
1551
|
-
if (name == "flathub") {
|
|
1552
|
-
found=1
|
|
1553
|
-
exit
|
|
1554
|
-
}
|
|
1555
|
-
} END { exit (found ? 0 : 1) }'; then
|
|
1556
|
-
return 0
|
|
1557
|
-
fi
|
|
1558
|
-
|
|
1559
|
-
return 1
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
ensure_flatpak_flathub_remote() {
|
|
1563
|
-
if ! manager_command_ready flatpak; then
|
|
1564
|
-
return 1
|
|
1565
|
-
fi
|
|
1566
|
-
|
|
1567
|
-
if flatpak_has_flathub_remote; then
|
|
1568
|
-
return 0
|
|
1569
|
-
fi
|
|
1570
|
-
|
|
1571
|
-
flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo 2>/dev/null ||
|
|
1572
|
-
run_as_root flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo 2>/dev/null ||
|
|
1573
|
-
return 1
|
|
1574
|
-
|
|
1575
|
-
flatpak_has_flathub_remote
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1578
|
-
winget_has_default_source() {
|
|
1579
|
-
if ! manager_command_ready winget; then
|
|
1580
|
-
return 1
|
|
1581
|
-
fi
|
|
1582
|
-
|
|
1583
|
-
if winget source list 2>/dev/null | awk '
|
|
1584
|
-
{
|
|
1585
|
-
line=$0
|
|
1586
|
-
sub(/^[[:space:]]+/, "", line)
|
|
1587
|
-
if (line == "") {
|
|
1588
|
-
next
|
|
1589
|
-
}
|
|
1590
|
-
split(line, cols, /[[:space:]]+/)
|
|
1591
|
-
if (tolower(cols[1]) == "winget") {
|
|
1592
|
-
found=1
|
|
1593
|
-
exit
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
END { exit (found ? 0 : 1) }
|
|
1597
|
-
'; then
|
|
1598
|
-
return 0
|
|
1599
|
-
fi
|
|
1600
|
-
|
|
1601
|
-
return 1
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
choco_has_any_sources() {
|
|
1605
|
-
if ! manager_command_ready choco; then
|
|
1606
|
-
return 1
|
|
1607
|
-
fi
|
|
1608
|
-
|
|
1609
|
-
if choco source list --limit-output 2>/dev/null | awk -F'|' 'NF >= 2 && $1 != "" { found=1; exit } END { exit (found ? 0 : 1) }'; then
|
|
1610
|
-
return 0
|
|
1611
|
-
fi
|
|
1612
|
-
|
|
1613
|
-
return 1
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
scoop_has_any_buckets() {
|
|
1617
|
-
if ! manager_command_ready scoop; then
|
|
1618
|
-
return 1
|
|
1619
|
-
fi
|
|
1620
|
-
|
|
1621
|
-
if scoop bucket list 2>/dev/null | awk '
|
|
1622
|
-
{
|
|
1623
|
-
line=$0
|
|
1624
|
-
sub(/^[[:space:]]+/, "", line)
|
|
1625
|
-
if (line == "") {
|
|
1626
|
-
next
|
|
1627
|
-
}
|
|
1628
|
-
if (tolower(line) ~ /^name[[:space:]]+/) {
|
|
1629
|
-
next
|
|
1630
|
-
}
|
|
1631
|
-
if (line ~ /^[-[:space:]]+$/) {
|
|
1632
|
-
next
|
|
1633
|
-
}
|
|
1634
|
-
split(line, cols, /[[:space:]]+/)
|
|
1635
|
-
if (length(cols[2]) > 0 && (cols[2] ~ /^https?:\/\// || cols[2] ~ /^git@/ || cols[2] ~ /^ssh:\/\// || cols[2] ~ /^file:\/\// || cols[2] ~ /^\//)) {
|
|
1636
|
-
found=1
|
|
1637
|
-
exit
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
END { exit (found ? 0 : 1) }
|
|
1641
|
-
'; then
|
|
1642
|
-
return 0
|
|
1643
|
-
fi
|
|
1644
|
-
|
|
1645
|
-
return 1
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
manager_no_query_setup_message() {
|
|
1649
|
-
local manager="$1"
|
|
1650
|
-
|
|
1651
|
-
case "${manager}" in
|
|
1652
|
-
flatpak)
|
|
1653
|
-
if ! flatpak_has_flathub_remote; then
|
|
1654
|
-
ensure_flatpak_flathub_remote >/dev/null 2>&1 || true
|
|
1655
|
-
fi
|
|
1656
|
-
if ! flatpak_has_flathub_remote; then
|
|
1657
|
-
printf "%s" "Flatpak has no remotes configured. Add Flathub with: flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo"
|
|
1658
|
-
return 0
|
|
1659
|
-
fi
|
|
1660
|
-
;;
|
|
1661
|
-
winget)
|
|
1662
|
-
if ! winget_has_default_source; then
|
|
1663
|
-
printf "%s" "WinGet source 'winget' is not configured. Restore it with: winget source reset --force"
|
|
1664
|
-
return 0
|
|
1665
|
-
fi
|
|
1666
|
-
;;
|
|
1667
|
-
choco)
|
|
1668
|
-
if ! choco_has_any_sources; then
|
|
1669
|
-
printf "%s" "Chocolatey has no package sources configured. Add the default source with: choco source add -n=chocolatey -s=https://community.chocolatey.org/api/v2/"
|
|
1670
|
-
return 0
|
|
1671
|
-
fi
|
|
1672
|
-
;;
|
|
1673
|
-
scoop)
|
|
1674
|
-
if ! scoop_has_any_buckets; then
|
|
1675
|
-
printf "%s" "Scoop has no buckets configured. Add the default bucket with: scoop bucket add main"
|
|
1676
|
-
return 0
|
|
1677
|
-
fi
|
|
1678
|
-
;;
|
|
1679
|
-
esac
|
|
1680
|
-
|
|
1681
|
-
return 1
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
manager_can_install_fzf() {
|
|
1685
|
-
local manager="$1"
|
|
1686
|
-
case "${manager}" in
|
|
1687
|
-
apt|dnf|pacman|zypper|emerge|brew|winget|choco|scoop|snap)
|
|
1688
|
-
return 0
|
|
1689
|
-
;;
|
|
1690
|
-
*)
|
|
1691
|
-
return 1
|
|
1692
|
-
;;
|
|
1693
|
-
esac
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
install_fzf_with_manager() {
|
|
1697
|
-
local manager="$1"
|
|
1698
|
-
|
|
1699
|
-
if [[ "${FPF_TEST_FZF_MANAGER_INSTALL_FAIL:-0}" == "1" ]]; then
|
|
1700
|
-
return 1
|
|
1701
|
-
fi
|
|
1702
|
-
|
|
1703
|
-
case "${manager}" in
|
|
1704
|
-
apt)
|
|
1705
|
-
run_as_root apt-get install -y fzf
|
|
1706
|
-
;;
|
|
1707
|
-
dnf)
|
|
1708
|
-
run_as_root dnf install -y fzf
|
|
1709
|
-
;;
|
|
1710
|
-
pacman)
|
|
1711
|
-
run_as_root pacman -S --needed fzf
|
|
1712
|
-
;;
|
|
1713
|
-
zypper)
|
|
1714
|
-
run_as_root zypper --non-interactive install --auto-agree-with-licenses fzf
|
|
1715
|
-
;;
|
|
1716
|
-
emerge)
|
|
1717
|
-
run_as_root emerge --ask=n app-shells/fzf
|
|
1718
|
-
;;
|
|
1719
|
-
brew)
|
|
1720
|
-
brew install fzf
|
|
1721
|
-
;;
|
|
1722
|
-
winget)
|
|
1723
|
-
winget install --id junegunn.fzf --exact --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity ||
|
|
1724
|
-
winget install --id fzf --exact --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity
|
|
1725
|
-
;;
|
|
1726
|
-
choco)
|
|
1727
|
-
choco install fzf -y
|
|
1728
|
-
;;
|
|
1729
|
-
scoop)
|
|
1730
|
-
scoop install fzf
|
|
1731
|
-
;;
|
|
1732
|
-
snap)
|
|
1733
|
-
run_as_root snap install fzf
|
|
1734
|
-
;;
|
|
1735
|
-
*)
|
|
1736
|
-
return 1
|
|
1737
|
-
;;
|
|
1738
|
-
esac
|
|
1739
|
-
}
|
|
1740
|
-
|
|
1741
|
-
detect_fzf_release_asset() {
|
|
1742
|
-
local os=""
|
|
1743
|
-
local arch=""
|
|
1744
|
-
|
|
1745
|
-
os="$(uname -s)"
|
|
1746
|
-
arch="$(uname -m)"
|
|
1747
|
-
|
|
1748
|
-
case "${os}" in
|
|
1749
|
-
Linux)
|
|
1750
|
-
case "${arch}" in
|
|
1751
|
-
x86_64|amd64) printf "linux_amd64.tar.gz" ;;
|
|
1752
|
-
aarch64|arm64) printf "linux_arm64.tar.gz" ;;
|
|
1753
|
-
armv7l|armv7*) printf "linux_armv7.tar.gz" ;;
|
|
1754
|
-
armv6l|armv6*) printf "linux_armv6.tar.gz" ;;
|
|
1755
|
-
*) return 1 ;;
|
|
1756
|
-
esac
|
|
1757
|
-
;;
|
|
1758
|
-
Darwin)
|
|
1759
|
-
case "${arch}" in
|
|
1760
|
-
x86_64|amd64) printf "darwin_amd64.tar.gz" ;;
|
|
1761
|
-
arm64|aarch64) printf "darwin_arm64.tar.gz" ;;
|
|
1762
|
-
*) return 1 ;;
|
|
1763
|
-
esac
|
|
1764
|
-
;;
|
|
1765
|
-
*)
|
|
1766
|
-
return 1
|
|
1767
|
-
;;
|
|
1768
|
-
esac
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
resolve_fzf_release_url() {
|
|
1772
|
-
local asset_suffix="$1"
|
|
1773
|
-
local api_url="https://api.github.com/repos/junegunn/fzf/releases/latest"
|
|
1774
|
-
local api_payload=""
|
|
1775
|
-
local asset_url=""
|
|
1776
|
-
|
|
1777
|
-
if [[ -n "${FPF_FZF_BOOTSTRAP_URL:-}" ]]; then
|
|
1778
|
-
printf "%s" "${FPF_FZF_BOOTSTRAP_URL}"
|
|
1779
|
-
return 0
|
|
1780
|
-
fi
|
|
1781
|
-
|
|
1782
|
-
command_exists curl || return 1
|
|
1783
|
-
api_payload="$(curl --silent --show-error --fail --location "${api_url}" 2>/dev/null || true)"
|
|
1784
|
-
[[ -n "${api_payload}" ]] || return 1
|
|
1785
|
-
|
|
1786
|
-
asset_url="$(printf "%s" "${api_payload}" | awk -F'"' -v suffix="${asset_suffix}" '
|
|
1787
|
-
$2 == "browser_download_url" {
|
|
1788
|
-
needle = "-" suffix
|
|
1789
|
-
if (index($4, needle) > 0) {
|
|
1790
|
-
print $4
|
|
1791
|
-
exit
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1794
|
-
')"
|
|
1795
|
-
|
|
1796
|
-
[[ -n "${asset_url}" ]] || return 1
|
|
1797
|
-
printf "%s" "${asset_url}"
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
install_fzf_from_release_fallback() {
|
|
1801
|
-
local asset_suffix=""
|
|
1802
|
-
local asset_url=""
|
|
1803
|
-
local archive_file=""
|
|
1804
|
-
local install_dir=""
|
|
1805
|
-
|
|
1806
|
-
if [[ "${FPF_TEST_BOOTSTRAP_FZF_FALLBACK:-0}" == "1" ]]; then
|
|
1807
|
-
if [[ -n "${FPF_TEST_MOCKCMD_PATH:-}" && -n "${FPF_TEST_MOCK_BIN:-}" ]]; then
|
|
1808
|
-
ln -sf "${FPF_TEST_MOCKCMD_PATH}" "${FPF_TEST_MOCK_BIN}/fzf"
|
|
1809
|
-
return 0
|
|
1810
|
-
fi
|
|
1811
|
-
return 1
|
|
1812
|
-
fi
|
|
1813
|
-
|
|
1814
|
-
asset_suffix="$(detect_fzf_release_asset)" || return 1
|
|
1815
|
-
asset_url="$(resolve_fzf_release_url "${asset_suffix}")" || return 1
|
|
1816
|
-
archive_file="$(mktemp "${SESSION_TMP_ROOT}/fzf-bootstrap.XXXXXX.tar.gz")"
|
|
1817
|
-
install_dir="${SESSION_TMP_ROOT}/fzf-bootstrap/bin"
|
|
1818
|
-
|
|
1819
|
-
mkdir -p "${install_dir}"
|
|
1820
|
-
|
|
1821
|
-
if ! curl --silent --show-error --fail --location --output "${archive_file}" "${asset_url}"; then
|
|
1822
|
-
rm -f "${archive_file}"
|
|
1823
|
-
return 1
|
|
1824
|
-
fi
|
|
1825
|
-
|
|
1826
|
-
if ! tar -xzf "${archive_file}" -C "${install_dir}"; then
|
|
1827
|
-
rm -f "${archive_file}"
|
|
1828
|
-
return 1
|
|
1829
|
-
fi
|
|
1830
|
-
|
|
1831
|
-
rm -f "${archive_file}"
|
|
1832
|
-
chmod +x "${install_dir}/fzf" 2>/dev/null || true
|
|
1833
|
-
[[ -x "${install_dir}/fzf" ]] || return 1
|
|
1834
|
-
|
|
1835
|
-
PATH="${install_dir}:${PATH}"
|
|
1836
|
-
export PATH
|
|
1837
|
-
return 0
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
build_fzf_bootstrap_candidates() {
|
|
1841
|
-
local seen=""
|
|
1842
|
-
local manager
|
|
1843
|
-
|
|
1844
|
-
for manager in "$@"; do
|
|
1845
|
-
[[ -n "${manager}" ]] || continue
|
|
1846
|
-
manager_can_install_fzf "${manager}" || continue
|
|
1847
|
-
manager_command_ready "${manager}" || continue
|
|
1848
|
-
case " ${seen} " in
|
|
1849
|
-
*" ${manager} "*)
|
|
1850
|
-
continue
|
|
1851
|
-
;;
|
|
1852
|
-
esac
|
|
1853
|
-
printf "%s\n" "${manager}"
|
|
1854
|
-
seen+=" ${manager}"
|
|
1855
|
-
done
|
|
1856
|
-
|
|
1857
|
-
if [[ -n "${seen}" ]]; then
|
|
1858
|
-
return
|
|
1859
|
-
fi
|
|
1860
|
-
|
|
1861
|
-
for manager in apt dnf pacman zypper emerge brew winget choco scoop snap; do
|
|
1862
|
-
manager_command_ready "${manager}" || continue
|
|
1863
|
-
case " ${seen} " in
|
|
1864
|
-
*" ${manager} "*)
|
|
1865
|
-
continue
|
|
1866
|
-
;;
|
|
1867
|
-
esac
|
|
1868
|
-
printf "%s\n" "${manager}"
|
|
1869
|
-
seen+=" ${manager}"
|
|
1870
|
-
done
|
|
1871
|
-
}
|
|
1872
|
-
|
|
1873
|
-
ensure_fzf() {
|
|
1874
|
-
local candidates=()
|
|
1875
|
-
local manager
|
|
1876
|
-
|
|
1877
|
-
if fzf_command_available; then
|
|
1878
|
-
return
|
|
1879
|
-
fi
|
|
1880
|
-
|
|
1881
|
-
while IFS= read -r manager; do
|
|
1882
|
-
[[ -n "${manager}" ]] || continue
|
|
1883
|
-
candidates+=("${manager}")
|
|
1884
|
-
done < <(build_fzf_bootstrap_candidates "$@")
|
|
1885
|
-
|
|
1886
|
-
if [[ "${#candidates[@]}" -eq 0 ]]; then
|
|
1887
|
-
die "fzf is required and no compatible manager is available to auto-install it"
|
|
1888
|
-
fi
|
|
1889
|
-
|
|
1890
|
-
local candidate_labels
|
|
1891
|
-
candidate_labels="$(join_manager_labels "${candidates[@]-}")"
|
|
1892
|
-
|
|
1893
|
-
log "fzf is missing. Auto-installing with: ${candidate_labels}"
|
|
1894
|
-
|
|
1895
|
-
for manager in "${candidates[@]-}"; do
|
|
1896
|
-
log "Attempting fzf install with $(manager_label "${manager}")"
|
|
1897
|
-
if install_fzf_with_manager "${manager}"; then
|
|
1898
|
-
if fzf_command_available; then
|
|
1899
|
-
return
|
|
1900
|
-
fi
|
|
1901
|
-
fi
|
|
1902
|
-
done
|
|
1903
|
-
|
|
1904
|
-
log "Package-manager bootstrap did not provide fzf. Trying release binary fallback."
|
|
1905
|
-
if install_fzf_from_release_fallback && fzf_command_available; then
|
|
1906
|
-
return
|
|
1907
|
-
fi
|
|
1908
|
-
|
|
1909
|
-
die "Failed to auto-install fzf. Install fzf manually and rerun."
|
|
1910
|
-
}
|
|
1911
|
-
|
|
1912
|
-
normalize_manager() {
|
|
1913
|
-
local manager="$1"
|
|
1914
|
-
|
|
1915
|
-
manager="$(trim_whitespace "${manager}")"
|
|
1916
|
-
manager="${manager,,}"
|
|
1917
|
-
|
|
1918
|
-
case "${manager}" in
|
|
1919
|
-
homebrew)
|
|
1920
|
-
manager="brew"
|
|
1921
|
-
;;
|
|
1922
|
-
chocolatey|chocolate)
|
|
1923
|
-
manager="choco"
|
|
1924
|
-
;;
|
|
1925
|
-
"portage (emerge)"|portage-emerge|portage)
|
|
1926
|
-
manager="emerge"
|
|
1927
|
-
;;
|
|
1928
|
-
win-get)
|
|
1929
|
-
manager="winget"
|
|
1930
|
-
;;
|
|
1931
|
-
esac
|
|
1932
|
-
|
|
1933
|
-
printf "%s" "${manager}"
|
|
1934
|
-
}
|
|
1935
|
-
|
|
1936
|
-
os_release_field() {
|
|
1937
|
-
local file_path="$1"
|
|
1938
|
-
local field_name="$2"
|
|
1939
|
-
|
|
1940
|
-
awk -v key="${field_name}" '
|
|
1941
|
-
index($0, key "=") == 1 {
|
|
1942
|
-
value = substr($0, index($0, "=") + 1)
|
|
1943
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
|
|
1944
|
-
if (value ~ /^".*"$/ || value ~ /^\047.*\047$/) {
|
|
1945
|
-
value = substr(value, 2, length(value) - 2)
|
|
1946
|
-
}
|
|
1947
|
-
print tolower(value)
|
|
1948
|
-
exit
|
|
1949
|
-
}
|
|
1950
|
-
' "${file_path}"
|
|
1951
|
-
}
|
|
1952
|
-
|
|
1953
|
-
manager_label() {
|
|
1954
|
-
local manager="$1"
|
|
1955
|
-
case "${manager}" in
|
|
1956
|
-
apt) printf "APT" ;;
|
|
1957
|
-
dnf) printf "DNF" ;;
|
|
1958
|
-
pacman) printf "Pacman" ;;
|
|
1959
|
-
zypper) printf "Zypper" ;;
|
|
1960
|
-
emerge) printf "Portage (emerge)" ;;
|
|
1961
|
-
brew) printf "Homebrew" ;;
|
|
1962
|
-
winget) printf "WinGet" ;;
|
|
1963
|
-
choco) printf "Chocolatey" ;;
|
|
1964
|
-
scoop) printf "Scoop" ;;
|
|
1965
|
-
snap) printf "Snap" ;;
|
|
1966
|
-
flatpak) printf "Flatpak" ;;
|
|
1967
|
-
npm) printf "npm" ;;
|
|
1968
|
-
bun) printf "bun" ;;
|
|
1969
|
-
*) printf "%s" "${manager}" ;;
|
|
1970
|
-
esac
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
detect_default_manager() {
|
|
1974
|
-
local os
|
|
1975
|
-
os="$(uname -s)"
|
|
1976
|
-
|
|
1977
|
-
if [[ "${os}" == "Darwin" ]]; then
|
|
1978
|
-
if command_exists brew; then
|
|
1979
|
-
printf "brew"
|
|
1980
|
-
return
|
|
1981
|
-
fi
|
|
1982
|
-
fi
|
|
1983
|
-
|
|
1984
|
-
if [[ "${os}" == MINGW* || "${os}" == MSYS* || "${os}" == CYGWIN* || "${os}" == "Windows_NT" ]]; then
|
|
1985
|
-
if command_exists winget; then printf "winget"; return; fi
|
|
1986
|
-
if command_exists choco; then printf "choco"; return; fi
|
|
1987
|
-
if command_exists scoop; then printf "scoop"; return; fi
|
|
1988
|
-
if command_exists bun; then printf "bun"; return; fi
|
|
1989
|
-
if command_exists npm; then printf "npm"; return; fi
|
|
1990
|
-
fi
|
|
1991
|
-
|
|
1992
|
-
if [[ "${os}" == "Linux" ]]; then
|
|
1993
|
-
local distro_id=""
|
|
1994
|
-
local distro_like=""
|
|
1995
|
-
local os_release_file="${FPF_OS_RELEASE_FILE:-}"
|
|
1996
|
-
|
|
1997
|
-
if [[ -n "${os_release_file}" && ! -r "${os_release_file}" ]]; then
|
|
1998
|
-
die "FPF_OS_RELEASE_FILE is set but not readable: ${os_release_file}"
|
|
1999
|
-
fi
|
|
2000
|
-
|
|
2001
|
-
if [[ -z "${os_release_file}" && -r /etc/os-release ]]; then
|
|
2002
|
-
os_release_file="/etc/os-release"
|
|
2003
|
-
elif [[ -z "${os_release_file}" && -r /usr/lib/os-release ]]; then
|
|
2004
|
-
os_release_file="/usr/lib/os-release"
|
|
2005
|
-
fi
|
|
2006
|
-
|
|
2007
|
-
if [[ -n "${os_release_file}" ]]; then
|
|
2008
|
-
distro_id="$(os_release_field "${os_release_file}" "ID")"
|
|
2009
|
-
distro_like="$(os_release_field "${os_release_file}" "ID_LIKE")"
|
|
2010
|
-
fi
|
|
2011
|
-
|
|
2012
|
-
case "${distro_id} ${distro_like}" in
|
|
2013
|
-
*arch*|*manjaro*)
|
|
2014
|
-
if command_exists pacman; then printf "pacman"; return; fi
|
|
2015
|
-
;;
|
|
2016
|
-
*ubuntu*|*debian*|*linuxmint*|*pop*|*elementary*)
|
|
2017
|
-
if command_exists apt-get; then printf "apt"; return; fi
|
|
2018
|
-
;;
|
|
2019
|
-
*fedora*|*rhel*|*centos*|*rocky*|*alma*)
|
|
2020
|
-
if command_exists dnf; then printf "dnf"; return; fi
|
|
2021
|
-
;;
|
|
2022
|
-
*opensuse*|*suse*|*sles*)
|
|
2023
|
-
if command_exists zypper; then printf "zypper"; return; fi
|
|
2024
|
-
;;
|
|
2025
|
-
*gentoo*)
|
|
2026
|
-
if command_exists emerge; then printf "emerge"; return; fi
|
|
2027
|
-
;;
|
|
2028
|
-
esac
|
|
2029
|
-
|
|
2030
|
-
if command_exists apt-get; then printf "apt"; return; fi
|
|
2031
|
-
if command_exists dnf; then printf "dnf"; return; fi
|
|
2032
|
-
if command_exists pacman; then printf "pacman"; return; fi
|
|
2033
|
-
if command_exists zypper; then printf "zypper"; return; fi
|
|
2034
|
-
if command_exists emerge; then printf "emerge"; return; fi
|
|
2035
|
-
if command_exists snap; then printf "snap"; return; fi
|
|
2036
|
-
if command_exists flatpak; then printf "flatpak"; return; fi
|
|
2037
|
-
if command_exists bun; then printf "bun"; return; fi
|
|
2038
|
-
if command_exists npm; then printf "npm"; return; fi
|
|
2039
|
-
fi
|
|
2040
|
-
|
|
2041
|
-
if command_exists brew; then printf "brew"; return; fi
|
|
2042
|
-
if command_exists winget; then printf "winget"; return; fi
|
|
2043
|
-
if command_exists choco; then printf "choco"; return; fi
|
|
2044
|
-
if command_exists scoop; then printf "scoop"; return; fi
|
|
2045
|
-
if command_exists bun; then printf "bun"; return; fi
|
|
2046
|
-
if command_exists npm; then printf "npm"; return; fi
|
|
2047
|
-
|
|
2048
|
-
die "Unable to auto-detect a supported package manager. Use --manager."
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
detect_default_managers() {
|
|
2052
|
-
local emitted=""
|
|
2053
|
-
local primary_manager=""
|
|
2054
|
-
local manager
|
|
2055
|
-
local prefer_bun=0
|
|
2056
|
-
|
|
2057
|
-
if manager_command_ready bun; then
|
|
2058
|
-
prefer_bun=1
|
|
2059
|
-
fi
|
|
2060
|
-
|
|
2061
|
-
add_detected_manager() {
|
|
2062
|
-
local manager_name="$1"
|
|
2063
|
-
[[ -n "${manager_name}" ]] || return
|
|
2064
|
-
|
|
2065
|
-
if [[ "${prefer_bun}" -eq 1 && "${manager_name}" == "npm" ]]; then
|
|
2066
|
-
return
|
|
2067
|
-
fi
|
|
2068
|
-
|
|
2069
|
-
case " ${emitted} " in
|
|
2070
|
-
*" ${manager_name} "*)
|
|
2071
|
-
return
|
|
2072
|
-
;;
|
|
2073
|
-
esac
|
|
2074
|
-
if manager_command_ready "${manager_name}"; then
|
|
2075
|
-
printf "%s\n" "${manager_name}"
|
|
2076
|
-
emitted+=" ${manager_name}"
|
|
2077
|
-
fi
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
primary_manager="$(detect_default_manager)"
|
|
2081
|
-
add_detected_manager "${primary_manager}"
|
|
2082
|
-
|
|
2083
|
-
for manager in apt dnf pacman zypper emerge brew winget choco scoop snap flatpak bun npm; do
|
|
2084
|
-
add_detected_manager "${manager}"
|
|
2085
|
-
done
|
|
2086
|
-
|
|
2087
|
-
if [[ -n "${emitted}" ]]; then
|
|
2088
|
-
return
|
|
2089
|
-
fi
|
|
2090
|
-
|
|
2091
|
-
die "Unable to auto-detect supported package managers. Use --manager."
|
|
2092
|
-
}
|
|
2093
|
-
|
|
2094
|
-
join_manager_labels() {
|
|
2095
|
-
local out=""
|
|
2096
|
-
local mgr
|
|
2097
|
-
|
|
2098
|
-
for mgr in "$@"; do
|
|
2099
|
-
[[ -n "${mgr}" ]] || continue
|
|
2100
|
-
if [[ -n "${out}" ]]; then
|
|
2101
|
-
out+=", "
|
|
2102
|
-
fi
|
|
2103
|
-
out+="$(manager_label "${mgr}")"
|
|
2104
|
-
done
|
|
2105
|
-
|
|
2106
|
-
printf "%s" "${out}"
|
|
2107
|
-
}
|
|
2108
|
-
|
|
2109
|
-
join_manager_labels_with_ids() {
|
|
2110
|
-
local out=""
|
|
2111
|
-
local mgr
|
|
2112
|
-
|
|
2113
|
-
for mgr in "$@"; do
|
|
2114
|
-
[[ -n "${mgr}" ]] || continue
|
|
2115
|
-
if [[ -n "${out}" ]]; then
|
|
2116
|
-
out+=", "
|
|
2117
|
-
fi
|
|
2118
|
-
out+="$(manager_label "${mgr}") (${mgr})"
|
|
2119
|
-
done
|
|
2120
|
-
|
|
2121
|
-
printf "%s" "${out}"
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
build_help_file() {
|
|
2125
|
-
local default_managers="$1"
|
|
2126
|
-
|
|
2127
|
-
cat >"${HELP_FILE}" <<EOF
|
|
2128
|
-
${SCRIPT_NAME} - fuzzy package finder
|
|
2129
|
-
|
|
2130
|
-
Syntax:
|
|
2131
|
-
${SCRIPT_NAME} [manager option] [action option] [query]
|
|
2132
|
-
${SCRIPT_NAME} -m|--manager <name> [action option] [query]
|
|
2133
|
-
|
|
2134
|
-
Default behavior:
|
|
2135
|
-
Fuzzy-search available packages and install selected items.
|
|
2136
|
-
|
|
2137
|
-
Detected default manager(s):
|
|
2138
|
-
${default_managers}
|
|
2139
|
-
|
|
2140
|
-
Action options:
|
|
2141
|
-
-l, --list-installed Fuzzy-search installed packages and show details
|
|
2142
|
-
-R, --remove Fuzzy-search installed packages and remove selected
|
|
2143
|
-
-U, --update Run manager update/upgrade flow
|
|
2144
|
-
--refresh Refresh manager package catalogs only
|
|
2145
|
-
-y, --yes Assume yes for confirmation prompts
|
|
2146
|
-
-v, --version Print version and exit
|
|
2147
|
-
-h, --help Show this help
|
|
2148
|
-
|
|
2149
|
-
Manager options (one or two-letter style):
|
|
2150
|
-
-ap, --apt Use APT
|
|
2151
|
-
-dn, --dnf Use DNF
|
|
2152
|
-
-pm, --pacman Use Pacman
|
|
2153
|
-
-zy, --zypper Use Zypper
|
|
2154
|
-
-em, --emerge Use Portage (emerge)
|
|
2155
|
-
-br, --brew Use Homebrew
|
|
2156
|
-
-wg, --winget Use WinGet
|
|
2157
|
-
-ch, --choco Use Chocolatey
|
|
2158
|
-
-sc, --scoop Use Scoop
|
|
2159
|
-
-sn, --snap Use Snap
|
|
2160
|
-
-fp, --flatpak Use Flatpak
|
|
2161
|
-
-np, --npm Use npm (global packages)
|
|
2162
|
-
-bn, --bun Use bun (global packages)
|
|
2163
|
-
-ad, --auto Force auto-detection mode
|
|
2164
|
-
|
|
2165
|
-
Examples:
|
|
2166
|
-
${SCRIPT_NAME} docker
|
|
2167
|
-
${SCRIPT_NAME} -dn nginx
|
|
2168
|
-
${SCRIPT_NAME} -ap -l openssl
|
|
2169
|
-
${SCRIPT_NAME} -br -R wget
|
|
2170
|
-
${SCRIPT_NAME} -sn firefox
|
|
2171
|
-
${SCRIPT_NAME} -fp org.gimp.GIMP
|
|
2172
|
-
${SCRIPT_NAME} -wg Microsoft.VisualStudioCode
|
|
2173
|
-
${SCRIPT_NAME} -np eslint
|
|
2174
|
-
${SCRIPT_NAME} -ch git
|
|
2175
|
-
${SCRIPT_NAME} -m apt ripgrep
|
|
2176
|
-
|
|
2177
|
-
Supported managers:
|
|
2178
|
-
$(manager_list)
|
|
2179
|
-
EOF
|
|
2180
|
-
}
|
|
2181
|
-
|
|
2182
|
-
build_keybind_file() {
|
|
2183
|
-
cat >"${KBINDS_FILE}" <<'EOF'
|
|
2184
|
-
Keybinds:
|
|
2185
|
-
|
|
2186
|
-
ctrl-h Show help in preview pane
|
|
2187
|
-
ctrl-k Show keybinds in preview pane
|
|
2188
|
-
ctrl-/ Toggle preview pane
|
|
2189
|
-
ctrl-n Move to next selected package
|
|
2190
|
-
ctrl-b Move to previous selected package
|
|
2191
|
-
EOF
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
print_help() {
|
|
2195
|
-
cat "${HELP_FILE}"
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
print_version() {
|
|
2199
|
-
printf "%s %s\n" "${SCRIPT_NAME}" "${SCRIPT_VERSION}"
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
|
-
parse_args() {
|
|
2203
|
-
local manager_value=""
|
|
2204
|
-
|
|
2205
|
-
while (($#)); do
|
|
2206
|
-
case "$1" in
|
|
2207
|
-
-h|--help)
|
|
2208
|
-
ACTION="help"
|
|
2209
|
-
;;
|
|
2210
|
-
-v|--version)
|
|
2211
|
-
ACTION="version"
|
|
2212
|
-
;;
|
|
2213
|
-
-l|--list-installed)
|
|
2214
|
-
ACTION="list"
|
|
2215
|
-
;;
|
|
2216
|
-
-R|--remove)
|
|
2217
|
-
ACTION="remove"
|
|
2218
|
-
;;
|
|
2219
|
-
-U|--update)
|
|
2220
|
-
ACTION="update"
|
|
2221
|
-
;;
|
|
2222
|
-
--refresh)
|
|
2223
|
-
ACTION="refresh"
|
|
2224
|
-
;;
|
|
2225
|
-
-y|--yes)
|
|
2226
|
-
ASSUME_YES="1"
|
|
2227
|
-
;;
|
|
2228
|
-
--feed-search)
|
|
2229
|
-
ACTION="feed-search"
|
|
2230
|
-
;;
|
|
2231
|
-
--dynamic-reload)
|
|
2232
|
-
ACTION="dynamic-reload"
|
|
2233
|
-
;;
|
|
2234
|
-
--ipc-reload)
|
|
2235
|
-
ACTION="ipc-reload"
|
|
2236
|
-
;;
|
|
2237
|
-
--ipc-query-notify)
|
|
2238
|
-
ACTION="ipc-query-notify"
|
|
2239
|
-
;;
|
|
2240
|
-
--preview-item)
|
|
2241
|
-
ACTION="preview-item"
|
|
2242
|
-
;;
|
|
2243
|
-
--bun-refresh-worker)
|
|
2244
|
-
ACTION="bun-refresh-worker"
|
|
2245
|
-
;;
|
|
2246
|
-
-ap|--apt)
|
|
2247
|
-
MANAGER_OVERRIDE="apt"
|
|
2248
|
-
;;
|
|
2249
|
-
-dn|--dnf)
|
|
2250
|
-
MANAGER_OVERRIDE="dnf"
|
|
2251
|
-
;;
|
|
2252
|
-
-pm|--pacman)
|
|
2253
|
-
MANAGER_OVERRIDE="pacman"
|
|
2254
|
-
;;
|
|
2255
|
-
-zy|--zypper)
|
|
2256
|
-
MANAGER_OVERRIDE="zypper"
|
|
2257
|
-
;;
|
|
2258
|
-
-em|--emerge)
|
|
2259
|
-
MANAGER_OVERRIDE="emerge"
|
|
2260
|
-
;;
|
|
2261
|
-
-br|--brew)
|
|
2262
|
-
MANAGER_OVERRIDE="brew"
|
|
2263
|
-
;;
|
|
2264
|
-
-wg|--winget)
|
|
2265
|
-
MANAGER_OVERRIDE="winget"
|
|
2266
|
-
;;
|
|
2267
|
-
-ch|--choco)
|
|
2268
|
-
MANAGER_OVERRIDE="choco"
|
|
2269
|
-
;;
|
|
2270
|
-
-sc|--scoop)
|
|
2271
|
-
MANAGER_OVERRIDE="scoop"
|
|
2272
|
-
;;
|
|
2273
|
-
-sn|--snap)
|
|
2274
|
-
MANAGER_OVERRIDE="snap"
|
|
2275
|
-
;;
|
|
2276
|
-
-fp|--flatpak)
|
|
2277
|
-
MANAGER_OVERRIDE="flatpak"
|
|
2278
|
-
;;
|
|
2279
|
-
-np|--npm)
|
|
2280
|
-
MANAGER_OVERRIDE="npm"
|
|
2281
|
-
;;
|
|
2282
|
-
-bn|--bun)
|
|
2283
|
-
MANAGER_OVERRIDE="bun"
|
|
2284
|
-
;;
|
|
2285
|
-
-ad|--auto)
|
|
2286
|
-
MANAGER_OVERRIDE=""
|
|
2287
|
-
;;
|
|
2288
|
-
-m|--manager)
|
|
2289
|
-
shift
|
|
2290
|
-
[[ $# -gt 0 ]] || die "Missing value for --manager"
|
|
2291
|
-
manager_value="$(trim_whitespace "$1")"
|
|
2292
|
-
[[ -n "${manager_value}" ]] || die "Missing value for --manager"
|
|
2293
|
-
[[ "${manager_value}" != -* ]] || die "Missing value for --manager"
|
|
2294
|
-
MANAGER_OVERRIDE="$(normalize_manager "${manager_value}")"
|
|
2295
|
-
;;
|
|
2296
|
-
-m=*|--manager=*)
|
|
2297
|
-
manager_value="$(trim_whitespace "${1#*=}")"
|
|
2298
|
-
[[ -n "${manager_value}" ]] || die "Missing value for --manager"
|
|
2299
|
-
[[ "${manager_value}" != -* ]] || die "Missing value for --manager"
|
|
2300
|
-
MANAGER_OVERRIDE="$(normalize_manager "${manager_value}")"
|
|
2301
|
-
;;
|
|
2302
|
-
--)
|
|
2303
|
-
shift
|
|
2304
|
-
while (($#)); do
|
|
2305
|
-
QUERY_PARTS+=("$1")
|
|
2306
|
-
shift
|
|
2307
|
-
done
|
|
2308
|
-
break
|
|
2309
|
-
;;
|
|
2310
|
-
-*)
|
|
2311
|
-
die "Invalid option: $1"
|
|
2312
|
-
;;
|
|
2313
|
-
*)
|
|
2314
|
-
QUERY_PARTS+=("$1")
|
|
2315
|
-
;;
|
|
2316
|
-
esac
|
|
2317
|
-
shift
|
|
2318
|
-
done
|
|
2319
|
-
}
|
|
2320
|
-
|
|
2321
|
-
join_query() {
|
|
2322
|
-
local query=""
|
|
2323
|
-
local part
|
|
2324
|
-
|
|
2325
|
-
if (( ${#QUERY_PARTS[@]} == 0 )); then
|
|
2326
|
-
printf ""
|
|
2327
|
-
return
|
|
2328
|
-
fi
|
|
2329
|
-
|
|
2330
|
-
for part in "${QUERY_PARTS[@]-}"; do
|
|
2331
|
-
if [[ -z "${query}" ]]; then
|
|
2332
|
-
query="${part}"
|
|
2333
|
-
else
|
|
2334
|
-
query+=" ${part}"
|
|
2335
|
-
fi
|
|
2336
|
-
done
|
|
2337
|
-
printf "%s" "${query}"
|
|
2338
|
-
}
|
|
2339
|
-
|
|
2340
|
-
dynamic_reload_enabled() {
|
|
2341
|
-
local manager_count="$1"
|
|
2342
|
-
local mode="${FPF_DYNAMIC_RELOAD:-always}"
|
|
2343
|
-
|
|
2344
|
-
case "${mode}" in
|
|
2345
|
-
always|auto|on|1|true|yes)
|
|
2346
|
-
return 0
|
|
2347
|
-
;;
|
|
2348
|
-
never|off|0|false|no)
|
|
2349
|
-
return 1
|
|
2350
|
-
;;
|
|
2351
|
-
single)
|
|
2352
|
-
[[ "${manager_count}" -eq 1 ]]
|
|
2353
|
-
;;
|
|
2354
|
-
*)
|
|
2355
|
-
return 0
|
|
2356
|
-
;;
|
|
2357
|
-
esac
|
|
2358
|
-
}
|
|
2359
|
-
|
|
2360
|
-
dynamic_reload_use_ipc() {
|
|
2361
|
-
local transport="${FPF_DYNAMIC_RELOAD_TRANSPORT:-reload}"
|
|
2362
|
-
|
|
2363
|
-
case "${transport}" in
|
|
2364
|
-
ipc|listen|http)
|
|
2365
|
-
fzf_supports_listen
|
|
2366
|
-
;;
|
|
2367
|
-
auto)
|
|
2368
|
-
fzf_supports_listen
|
|
2369
|
-
;;
|
|
2370
|
-
*)
|
|
2371
|
-
return 1
|
|
2372
|
-
;;
|
|
2373
|
-
esac
|
|
2374
|
-
}
|
|
2375
|
-
|
|
2376
|
-
rank_display_rows_by_query() {
|
|
2377
|
-
local query="$1"
|
|
2378
|
-
local input_file="$2"
|
|
2379
|
-
local ranked_file
|
|
2380
|
-
local has_exact=0
|
|
2381
|
-
local candidate
|
|
2382
|
-
|
|
2383
|
-
if [[ "${FPF_USE_GO_DISPLAY_PIPELINE:-0}" == "1" && -n "${FPF_SELF_PATH:-}" && -x "${FPF_SELF_PATH}" ]]; then
|
|
2384
|
-
"${FPF_SELF_PATH}" --go-rank-display --go-query "${query}" --go-input "${input_file}"
|
|
2385
|
-
return $?
|
|
2386
|
-
fi
|
|
2387
|
-
|
|
2388
|
-
[[ -n "${query}" ]] || return 0
|
|
2389
|
-
|
|
2390
|
-
while IFS= read -r candidate; do
|
|
2391
|
-
[[ -n "${candidate}" ]] || continue
|
|
2392
|
-
if awk -F'\t' -v cand="${candidate}" 'tolower($2) == tolower(cand) { found=1; exit } END { exit (found ? 0 : 1) }' "${input_file}"; then
|
|
2393
|
-
has_exact=1
|
|
2394
|
-
break
|
|
2395
|
-
fi
|
|
2396
|
-
done < <(exact_query_candidates "${query}" | awk '!seen[$0]++')
|
|
2397
|
-
|
|
2398
|
-
ranked_file="$(mktemp "${SESSION_TMP_ROOT}/ranked.XXXXXX")"
|
|
2399
|
-
|
|
2400
|
-
awk -F'\t' -v query="${query}" -v has_exact="${has_exact}" '
|
|
2401
|
-
function lower(s) { return tolower(s) }
|
|
2402
|
-
function normalize(s, t) {
|
|
2403
|
-
t = lower(s)
|
|
2404
|
-
gsub(/[^[:alnum:]]+/, "", t)
|
|
2405
|
-
return t
|
|
2406
|
-
}
|
|
2407
|
-
BEGIN {
|
|
2408
|
-
q = lower(query)
|
|
2409
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", q)
|
|
2410
|
-
q_norm = normalize(q)
|
|
2411
|
-
|
|
2412
|
-
token_total = split(q, raw_tokens, /[^[:alnum:]]+/)
|
|
2413
|
-
query_token_count = 0
|
|
2414
|
-
for (i = 1; i <= token_total; i++) {
|
|
2415
|
-
if (raw_tokens[i] != "") {
|
|
2416
|
-
query_tokens[++query_token_count] = raw_tokens[i]
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
{
|
|
2421
|
-
mgr = lower($1)
|
|
2422
|
-
pkg = $2
|
|
2423
|
-
desc = $3
|
|
2424
|
-
|
|
2425
|
-
pkg_l = lower(pkg)
|
|
2426
|
-
desc_l = lower(desc)
|
|
2427
|
-
pkg_norm = normalize(pkg_l)
|
|
2428
|
-
desc_norm = normalize(desc_l)
|
|
2429
|
-
|
|
2430
|
-
pkg_token_hits = 0
|
|
2431
|
-
desc_token_hits = 0
|
|
2432
|
-
for (i = 1; i <= query_token_count; i++) {
|
|
2433
|
-
token = query_tokens[i]
|
|
2434
|
-
if (index(pkg_l, token) > 0 || index(pkg_norm, token) > 0) {
|
|
2435
|
-
pkg_token_hits++
|
|
2436
|
-
}
|
|
2437
|
-
if (index(desc_l, token) > 0 || index(desc_norm, token) > 0) {
|
|
2438
|
-
desc_token_hits++
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
|
|
2442
|
-
pkg_token_count = 0
|
|
2443
|
-
split(pkg_l, pkg_parts, /[^[:alnum:]]+/)
|
|
2444
|
-
for (i in pkg_parts) {
|
|
2445
|
-
if (pkg_parts[i] != "") {
|
|
2446
|
-
pkg_token_count++
|
|
2447
|
-
}
|
|
2448
|
-
}
|
|
2449
|
-
|
|
2450
|
-
score = 12
|
|
2451
|
-
if (q != "") {
|
|
2452
|
-
if (pkg_l == q || (q_norm != "" && pkg_norm == q_norm)) {
|
|
2453
|
-
score = 0
|
|
2454
|
-
} else if (q_norm != "" && index(pkg_norm, q_norm) == 1) {
|
|
2455
|
-
score = 1
|
|
2456
|
-
} else if (query_token_count > 1 && pkg_token_hits == query_token_count) {
|
|
2457
|
-
score = 2
|
|
2458
|
-
} else if (q_norm != "" && index(pkg_norm, q_norm) > 0) {
|
|
2459
|
-
score = 3
|
|
2460
|
-
} else if (query_token_count > 0 && pkg_token_hits > 0) {
|
|
2461
|
-
score = 4
|
|
2462
|
-
} else if (query_token_count > 0 && desc_token_hits == query_token_count) {
|
|
2463
|
-
score = 5
|
|
2464
|
-
} else if (query_token_count > 0 && desc_token_hits > 0) {
|
|
2465
|
-
score = 6
|
|
2466
|
-
}
|
|
2467
|
-
}
|
|
2468
|
-
|
|
2469
|
-
if (q != "" && has_exact == 1 && pkg_token_hits == query_token_count && query_token_count > 0 && pkg_token_count > query_token_count) {
|
|
2470
|
-
score += 5
|
|
2471
|
-
}
|
|
2472
|
-
|
|
2473
|
-
if (q != "" && desc_l ~ /(plugin|template|starter|boilerplate|router|hooks?|mcp|integration)/) {
|
|
2474
|
-
score += 2
|
|
2475
|
-
}
|
|
2476
|
-
|
|
2477
|
-
mgr_bias = 0
|
|
2478
|
-
if (mgr == "npm") {
|
|
2479
|
-
mgr_bias = 4
|
|
2480
|
-
} else if (mgr == "bun") {
|
|
2481
|
-
mgr_bias = 3
|
|
2482
|
-
}
|
|
2483
|
-
|
|
2484
|
-
print score "\t" mgr_bias "\t" (99 - pkg_token_hits) "\t" (99 - desc_token_hits) "\t" length(pkg) "\t" pkg_l "\t" $0
|
|
2485
|
-
}
|
|
2486
|
-
' "${input_file}" |
|
|
2487
|
-
sort -t $'\t' -k1,1n -k2,2n -k3,3n -k4,4n -k5,5n -k6,6 |
|
|
2488
|
-
awk -F'\t' '{ print $7 "\t" $8 "\t" $9 }' >"${ranked_file}"
|
|
2489
|
-
|
|
2490
|
-
mv "${ranked_file}" "${input_file}"
|
|
2491
|
-
}
|
|
2492
|
-
|
|
2493
|
-
exact_query_candidates() {
|
|
2494
|
-
local query="$1"
|
|
2495
|
-
local compact_query=""
|
|
2496
|
-
local dashed_query=""
|
|
2497
|
-
local underscored_query=""
|
|
2498
|
-
local nospace_query=""
|
|
2499
|
-
local -a query_tokens=()
|
|
2500
|
-
|
|
2501
|
-
read -r -a query_tokens <<<"${query}"
|
|
2502
|
-
compact_query="${query_tokens[*]}"
|
|
2503
|
-
[[ -n "${compact_query}" ]] || return 0
|
|
2504
|
-
|
|
2505
|
-
printf "%s\n" "${compact_query}"
|
|
2506
|
-
|
|
2507
|
-
if [[ "${compact_query}" == *[[:space:]]* ]]; then
|
|
2508
|
-
dashed_query="${compact_query// /-}"
|
|
2509
|
-
underscored_query="${compact_query// /_}"
|
|
2510
|
-
nospace_query="${compact_query// /}"
|
|
2511
|
-
printf "%s\n" "${dashed_query}"
|
|
2512
|
-
printf "%s\n" "${underscored_query}"
|
|
2513
|
-
printf "%s\n" "${nospace_query}"
|
|
2514
|
-
fi
|
|
2515
|
-
}
|
|
2516
|
-
|
|
2517
|
-
manager_bun_search_entries_strict() {
|
|
2518
|
-
local query="$1"
|
|
2519
|
-
local effective_query="${query}"
|
|
2520
|
-
local line_limit=0
|
|
2521
|
-
local query_line_limit=40
|
|
2522
|
-
local effective_limit=0
|
|
2523
|
-
local bun_search_file
|
|
2524
|
-
|
|
2525
|
-
if [[ -z "${query}" ]]; then
|
|
2526
|
-
line_limit="${FPF_NO_QUERY_RESULT_LIMIT:-120}"
|
|
2527
|
-
else
|
|
2528
|
-
query_line_limit="${FPF_QUERY_PER_MANAGER_LIMIT:-40}"
|
|
2529
|
-
fi
|
|
2530
|
-
|
|
2531
|
-
if ! [[ "${line_limit}" =~ ^[0-9]+$ ]]; then
|
|
2532
|
-
line_limit=0
|
|
2533
|
-
fi
|
|
2534
|
-
|
|
2535
|
-
if ! [[ "${query_line_limit}" =~ ^[0-9]+$ ]]; then
|
|
2536
|
-
query_line_limit=40
|
|
2537
|
-
fi
|
|
2538
|
-
|
|
2539
|
-
if [[ "${line_limit}" -gt 0 ]]; then
|
|
2540
|
-
effective_limit="${line_limit}"
|
|
2541
|
-
else
|
|
2542
|
-
effective_limit="${query_line_limit}"
|
|
2543
|
-
fi
|
|
2544
|
-
|
|
2545
|
-
if [[ -z "${effective_query}" ]]; then
|
|
2546
|
-
effective_query="aa"
|
|
2547
|
-
fi
|
|
2548
|
-
|
|
2549
|
-
bun_search_file="$(mktemp "${SESSION_TMP_ROOT}/bun-search-strict.XXXXXX")"
|
|
2550
|
-
if ! bun search "${effective_query}" >"${bun_search_file}" 2>/dev/null; then
|
|
2551
|
-
rm -f "${bun_search_file}"
|
|
2552
|
-
return 1
|
|
2553
|
-
fi
|
|
2554
|
-
|
|
2555
|
-
{
|
|
2556
|
-
awk 'NR > 1 && NF > 0 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }' "${bun_search_file}"
|
|
2557
|
-
} | awk -F'\t' 'NF >= 1 { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' | awk -F'\t' '!seen[$1]++' | {
|
|
2558
|
-
if [[ "${effective_limit}" -gt 0 ]]; then
|
|
2559
|
-
awk -v limit="${effective_limit}" 'NR <= limit'
|
|
2560
|
-
else
|
|
2561
|
-
cat
|
|
2562
|
-
fi
|
|
2563
|
-
}
|
|
2564
|
-
|
|
2565
|
-
rm -f "${bun_search_file}"
|
|
2566
|
-
}
|
|
2567
|
-
|
|
2568
|
-
manager_search_entries_uncached() {
|
|
2569
|
-
local manager="$1"
|
|
2570
|
-
local query="$2"
|
|
2571
|
-
local effective_query="${query}"
|
|
2572
|
-
local npm_search_limit=500
|
|
2573
|
-
local line_limit=0
|
|
2574
|
-
local query_line_limit=40
|
|
2575
|
-
local effective_limit=0
|
|
2576
|
-
|
|
2577
|
-
if [[ -z "${query}" ]]; then
|
|
2578
|
-
npm_search_limit="${FPF_NO_QUERY_NPM_LIMIT:-120}"
|
|
2579
|
-
line_limit="${FPF_NO_QUERY_RESULT_LIMIT:-120}"
|
|
2580
|
-
else
|
|
2581
|
-
query_line_limit="${FPF_QUERY_PER_MANAGER_LIMIT:-40}"
|
|
2582
|
-
fi
|
|
2583
|
-
|
|
2584
|
-
if ! [[ "${npm_search_limit}" =~ ^[0-9]+$ ]] || [[ "${npm_search_limit}" -eq 0 ]]; then
|
|
2585
|
-
npm_search_limit=500
|
|
2586
|
-
fi
|
|
2587
|
-
|
|
2588
|
-
if ! [[ "${line_limit}" =~ ^[0-9]+$ ]]; then
|
|
2589
|
-
line_limit=0
|
|
2590
|
-
fi
|
|
2591
|
-
|
|
2592
|
-
if ! [[ "${query_line_limit}" =~ ^[0-9]+$ ]]; then
|
|
2593
|
-
query_line_limit=40
|
|
2594
|
-
fi
|
|
2595
|
-
|
|
2596
|
-
if [[ "${line_limit}" -gt 0 ]]; then
|
|
2597
|
-
effective_limit="${line_limit}"
|
|
2598
|
-
else
|
|
2599
|
-
effective_limit="${query_line_limit}"
|
|
2600
|
-
fi
|
|
2601
|
-
|
|
2602
|
-
if [[ -z "${effective_query}" ]]; then
|
|
2603
|
-
case "${manager}" in
|
|
2604
|
-
apt|dnf|pacman|zypper|emerge|choco|scoop|snap)
|
|
2605
|
-
effective_query="a"
|
|
2606
|
-
;;
|
|
2607
|
-
brew|npm|bun)
|
|
2608
|
-
effective_query="aa"
|
|
2609
|
-
;;
|
|
2610
|
-
winget)
|
|
2611
|
-
effective_query="aa"
|
|
2612
|
-
;;
|
|
2613
|
-
esac
|
|
2614
|
-
fi
|
|
2615
|
-
|
|
2616
|
-
if [[ "${FPF_USE_GO_SEARCH_ENTRIES:-0}" == "1" && -n "${FPF_SELF_PATH:-}" && -x "${FPF_SELF_PATH}" ]]; then
|
|
2617
|
-
case "${manager}" in
|
|
2618
|
-
apt|brew)
|
|
2619
|
-
;;
|
|
2620
|
-
flatpak)
|
|
2621
|
-
if [[ -z "${query}" ]]; then
|
|
2622
|
-
:
|
|
2623
|
-
else
|
|
2624
|
-
"${FPF_SELF_PATH}" \
|
|
2625
|
-
--go-search-entries \
|
|
2626
|
-
--go-manager "${manager}" \
|
|
2627
|
-
--go-query "${effective_query}" \
|
|
2628
|
-
--go-limit "${effective_limit}" \
|
|
2629
|
-
--go-npm-search-limit "${npm_search_limit}"
|
|
2630
|
-
return 0
|
|
2631
|
-
fi
|
|
2632
|
-
;;
|
|
2633
|
-
*)
|
|
2634
|
-
"${FPF_SELF_PATH}" \
|
|
2635
|
-
--go-search-entries \
|
|
2636
|
-
--go-manager "${manager}" \
|
|
2637
|
-
--go-query "${effective_query}" \
|
|
2638
|
-
--go-limit "${effective_limit}" \
|
|
2639
|
-
--go-npm-search-limit "${npm_search_limit}"
|
|
2640
|
-
return 0
|
|
2641
|
-
;;
|
|
2642
|
-
esac
|
|
2643
|
-
fi
|
|
2644
|
-
|
|
2645
|
-
case "${manager}" in
|
|
2646
|
-
apt)
|
|
2647
|
-
if search_entries_from_catalog_cache "${manager}" "${effective_query}"; then
|
|
2648
|
-
:
|
|
2649
|
-
elif [[ -n "${query}" ]] && search_catalog_async_prewarm_enabled; then
|
|
2650
|
-
start_search_catalog_prewarm_async "${manager}"
|
|
2651
|
-
apt-cache search -- "${effective_query}" 2>/dev/null |
|
|
2652
|
-
awk -F' - ' '{ name=$1; desc=$2; gsub(/^[[:space:]]+|[[:space:]]+$/, "", name); if (desc == "") desc="-"; print name "\t" desc }'
|
|
2653
|
-
elif ensure_search_catalog_cache "${manager}"; then
|
|
2654
|
-
search_entries_from_catalog_cache "${manager}" "${effective_query}" || true
|
|
2655
|
-
else
|
|
2656
|
-
apt-cache search -- "${effective_query}" 2>/dev/null |
|
|
2657
|
-
awk -F' - ' '{ name=$1; desc=$2; gsub(/^[[:space:]]+|[[:space:]]+$/, "", name); if (desc == "") desc="-"; print name "\t" desc }'
|
|
2658
|
-
fi
|
|
2659
|
-
;;
|
|
2660
|
-
dnf)
|
|
2661
|
-
local pattern="*"
|
|
2662
|
-
if [[ -n "${effective_query}" ]]; then
|
|
2663
|
-
pattern="*${effective_query}*"
|
|
2664
|
-
fi
|
|
2665
|
-
dnf -q list available "${pattern}" 2>/dev/null |
|
|
2666
|
-
awk 'NR > 1 && $1 !~ /^(Available|Last|Installed)/ { name=$1; sub(/\.[^.]+$/, "", name); print name "\t" $2 }'
|
|
2667
|
-
;;
|
|
2668
|
-
pacman)
|
|
2669
|
-
pacman -Ss -- "${effective_query}" 2>/dev/null |
|
|
2670
|
-
awk '
|
|
2671
|
-
NR % 2 == 1 {
|
|
2672
|
-
split($1, parts, "/")
|
|
2673
|
-
pkg = parts[2]
|
|
2674
|
-
next
|
|
2675
|
-
}
|
|
2676
|
-
NR % 2 == 0 {
|
|
2677
|
-
line = $0
|
|
2678
|
-
sub(/^[[:space:]]+/, "", line)
|
|
2679
|
-
if (pkg != "") print pkg "\t" line
|
|
2680
|
-
}
|
|
2681
|
-
'
|
|
2682
|
-
;;
|
|
2683
|
-
zypper)
|
|
2684
|
-
zypper --non-interactive --quiet search --details --type package "${effective_query}" 2>/dev/null |
|
|
2685
|
-
awk -F'|' '
|
|
2686
|
-
/^[[:space:]]*[ivp ][[:space:]]*\|/ {
|
|
2687
|
-
name=$3
|
|
2688
|
-
ver=$5
|
|
2689
|
-
repo=$7
|
|
2690
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
|
2691
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", ver)
|
|
2692
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", repo)
|
|
2693
|
-
if (name != "") print name "\tversion " ver " from " repo
|
|
2694
|
-
}
|
|
2695
|
-
'
|
|
2696
|
-
;;
|
|
2697
|
-
emerge)
|
|
2698
|
-
emerge --searchdesc --color=n "${effective_query}" 2>/dev/null |
|
|
2699
|
-
awk '
|
|
2700
|
-
/^\* / {
|
|
2701
|
-
atom=$2
|
|
2702
|
-
desc="-"
|
|
2703
|
-
next
|
|
2704
|
-
}
|
|
2705
|
-
/^[[:space:]]+Description:/ {
|
|
2706
|
-
line=$0
|
|
2707
|
-
sub(/^[[:space:]]+Description:[[:space:]]*/, "", line)
|
|
2708
|
-
desc=line
|
|
2709
|
-
if (atom != "") print atom "\t" desc
|
|
2710
|
-
atom=""
|
|
2711
|
-
}
|
|
2712
|
-
'
|
|
2713
|
-
;;
|
|
2714
|
-
brew)
|
|
2715
|
-
if search_entries_from_catalog_cache "${manager}" "${effective_query}"; then
|
|
2716
|
-
:
|
|
2717
|
-
elif [[ -n "${query}" ]] && search_catalog_async_prewarm_enabled; then
|
|
2718
|
-
start_search_catalog_prewarm_async "${manager}"
|
|
2719
|
-
brew search "${effective_query}" 2>/dev/null |
|
|
2720
|
-
awk 'NF >= 1 { print $1 "\t-" }'
|
|
2721
|
-
elif ensure_search_catalog_cache "${manager}"; then
|
|
2722
|
-
search_entries_from_catalog_cache "${manager}" "${effective_query}" || true
|
|
2723
|
-
else
|
|
2724
|
-
brew search "${effective_query}" 2>/dev/null |
|
|
2725
|
-
awk 'NF > 0 && $1 != "==>" { print $1 "\t-" }'
|
|
2726
|
-
fi
|
|
2727
|
-
;;
|
|
2728
|
-
winget)
|
|
2729
|
-
winget search "${effective_query}" --source winget --accept-source-agreements --disable-interactivity 2>/dev/null |
|
|
2730
|
-
awk '
|
|
2731
|
-
/^[[:space:]]*$/ { next }
|
|
2732
|
-
/^Name[[:space:]]+Id[[:space:]]+/ { next }
|
|
2733
|
-
/^[-[:space:]]+$/ { next }
|
|
2734
|
-
{
|
|
2735
|
-
line = $0
|
|
2736
|
-
sub(/^[[:space:]]+/, "", line)
|
|
2737
|
-
pkg = ""
|
|
2738
|
-
n = split(line, cols, /[[:space:]][[:space:]]+/)
|
|
2739
|
-
if (n >= 2) {
|
|
2740
|
-
pkg = cols[2]
|
|
2741
|
-
}
|
|
2742
|
-
if (pkg != "") {
|
|
2743
|
-
print pkg "\t-"
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
|
-
'
|
|
2747
|
-
;;
|
|
2748
|
-
choco)
|
|
2749
|
-
choco search "${effective_query}" --limit-output 2>/dev/null |
|
|
2750
|
-
awk -F'|' 'NF >= 1 && $1 != "" { ver=$2; if (ver == "") ver="-"; print $1 "\tversion " ver }'
|
|
2751
|
-
;;
|
|
2752
|
-
scoop)
|
|
2753
|
-
scoop search "${effective_query}" 2>/dev/null |
|
|
2754
|
-
awk '
|
|
2755
|
-
/^[[:space:]]*$/ { next }
|
|
2756
|
-
/^[-[:space:]]+$/ { next }
|
|
2757
|
-
/^Name[[:space:]]+/ { next }
|
|
2758
|
-
{
|
|
2759
|
-
name = $1
|
|
2760
|
-
$1 = ""
|
|
2761
|
-
sub(/^[[:space:]]+/, "", $0)
|
|
2762
|
-
if ($0 == "") $0 = "-"
|
|
2763
|
-
print name "\t" $0
|
|
2764
|
-
}
|
|
2765
|
-
'
|
|
2766
|
-
;;
|
|
2767
|
-
snap)
|
|
2768
|
-
snap find "${effective_query}" 2>/dev/null |
|
|
2769
|
-
awk '
|
|
2770
|
-
NR == 1 { next }
|
|
2771
|
-
NF > 0 {
|
|
2772
|
-
name=$1
|
|
2773
|
-
$1=""
|
|
2774
|
-
sub(/^[[:space:]]+/, "", $0)
|
|
2775
|
-
if ($0 == "") $0 = "-"
|
|
2776
|
-
print name "\t" $0
|
|
2777
|
-
}
|
|
2778
|
-
'
|
|
2779
|
-
;;
|
|
2780
|
-
flatpak)
|
|
2781
|
-
ensure_flatpak_flathub_remote >/dev/null 2>&1 || true
|
|
2782
|
-
if [[ -z "${effective_query}" ]]; then
|
|
2783
|
-
{
|
|
2784
|
-
flatpak remote-ls --app --columns=application,description flathub 2>/dev/null ||
|
|
2785
|
-
flatpak remote-ls --app --columns=application,description 2>/dev/null
|
|
2786
|
-
} |
|
|
2787
|
-
awk 'NR > 1 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }'
|
|
2788
|
-
else
|
|
2789
|
-
{
|
|
2790
|
-
flatpak search --columns=application,description "${effective_query}" 2>/dev/null ||
|
|
2791
|
-
flatpak search "${effective_query}" 2>/dev/null
|
|
2792
|
-
} |
|
|
2793
|
-
awk 'NR > 1 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }'
|
|
2794
|
-
fi
|
|
2795
|
-
;;
|
|
2796
|
-
npm)
|
|
2797
|
-
npm search "${effective_query}" --searchlimit="${npm_search_limit}" --parseable 2>/dev/null |
|
|
2798
|
-
awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
|
|
2799
|
-
;;
|
|
2800
|
-
bun)
|
|
2801
|
-
{
|
|
2802
|
-
local bun_search_file
|
|
2803
|
-
bun_search_file="$(mktemp "${SESSION_TMP_ROOT}/bun-search.XXXXXX")"
|
|
2804
|
-
if bun search "${effective_query}" >"${bun_search_file}" 2>/dev/null; then
|
|
2805
|
-
awk 'NR > 1 && NF > 0 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }' "${bun_search_file}"
|
|
2806
|
-
elif command_exists npm; then
|
|
2807
|
-
npm search "${effective_query}" --searchlimit="${npm_search_limit}" --parseable 2>/dev/null |
|
|
2808
|
-
awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
|
|
2809
|
-
fi
|
|
2810
|
-
rm -f "${bun_search_file}"
|
|
2811
|
-
} || true
|
|
2812
|
-
;;
|
|
2813
|
-
esac | awk -F'\t' 'NF >= 1 { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' | awk -F'\t' '!seen[$1]++' | {
|
|
2814
|
-
if [[ "${effective_limit}" -gt 0 ]]; then
|
|
2815
|
-
awk -v limit="${effective_limit}" 'NR <= limit'
|
|
2816
|
-
else
|
|
2817
|
-
cat
|
|
2818
|
-
fi
|
|
2819
|
-
} || true
|
|
2820
|
-
}
|
|
2821
|
-
|
|
2822
|
-
manager_search_entries() {
|
|
2823
|
-
local manager="$1"
|
|
2824
|
-
local query="$2"
|
|
2825
|
-
local query_cache_enabled="0"
|
|
2826
|
-
local query_cache_setting="${FPF_ENABLE_QUERY_CACHE:-auto}"
|
|
2827
|
-
local query_cache_ttl="0"
|
|
2828
|
-
local bun_cache_ttl="900"
|
|
2829
|
-
local bypass_query_cache="${FPF_BYPASS_QUERY_CACHE:-0}"
|
|
2830
|
-
local flags
|
|
2831
|
-
local key
|
|
2832
|
-
local fingerprint
|
|
2833
|
-
local cache_file
|
|
2834
|
-
local output_tmp
|
|
2835
|
-
local generation
|
|
2836
|
-
local should_async_refresh=0
|
|
2837
|
-
|
|
2838
|
-
initialize_cache_root
|
|
2839
|
-
|
|
2840
|
-
flags="$(query_cache_flags)"
|
|
2841
|
-
query_cache_setting="$(trim_whitespace "${query_cache_setting}")"
|
|
2842
|
-
query_cache_setting="${query_cache_setting,,}"
|
|
2843
|
-
query_cache_ttl="$(query_cache_ttl_seconds_for_manager "${manager}")"
|
|
2844
|
-
|
|
2845
|
-
if [[ "${manager}" == "bun" ]]; then
|
|
2846
|
-
bun_cache_ttl="${query_cache_ttl}"
|
|
2847
|
-
fi
|
|
2848
|
-
|
|
2849
|
-
case "${bypass_query_cache}" in
|
|
2850
|
-
1|true|yes|on)
|
|
2851
|
-
;;
|
|
2852
|
-
*)
|
|
2853
|
-
case "${query_cache_setting}" in
|
|
2854
|
-
1|true|yes|on)
|
|
2855
|
-
query_cache_enabled="1"
|
|
2856
|
-
;;
|
|
2857
|
-
auto|"")
|
|
2858
|
-
if query_cache_default_enabled_for_manager "${manager}"; then
|
|
2859
|
-
query_cache_enabled="1"
|
|
2860
|
-
fi
|
|
2861
|
-
;;
|
|
2862
|
-
esac
|
|
2863
|
-
;;
|
|
2864
|
-
esac
|
|
2865
|
-
|
|
2866
|
-
key="$(cache_query_key "${manager}" "${query}" "${flags}")"
|
|
2867
|
-
fingerprint="$(cache_fingerprint "${manager}" "${query}" "${flags}")"
|
|
2868
|
-
cache_file="$(cache_path_for_key "${key}")"
|
|
2869
|
-
|
|
2870
|
-
if [[ "${manager}" == "bun" && "${query_cache_enabled}" == "1" && ( "${ACTION}" == "feed-search" || "${ACTION}" == "ipc-query-notify" ) ]]; then
|
|
2871
|
-
if [[ -s "${cache_file}" ]]; then
|
|
2872
|
-
cache_emit_query_rows_if_valid "${cache_file}" || true
|
|
2873
|
-
fi
|
|
2874
|
-
|
|
2875
|
-
if cache_is_fresh_with_ttl "${key}" "${bun_cache_ttl}"; then
|
|
2876
|
-
return
|
|
2877
|
-
fi
|
|
2878
|
-
|
|
2879
|
-
generation="$(bun_generation_next "${key}")"
|
|
2880
|
-
if [[ -n "${FZF_PORT:-}" && "${FPF_BUN_SKIP_REFRESH_SCHEDULE:-0}" != "1" ]]; then
|
|
2881
|
-
should_async_refresh=1
|
|
2882
|
-
fi
|
|
2883
|
-
|
|
2884
|
-
if [[ "${FPF_BUN_TEST_SYNC_REFRESH:-0}" == "1" ]]; then
|
|
2885
|
-
should_async_refresh=0
|
|
2886
|
-
fi
|
|
2887
|
-
|
|
2888
|
-
if [[ "${should_async_refresh}" -eq 1 ]]; then
|
|
2889
|
-
start_bun_refresh_worker_async "${manager}" "${query}" "${flags}" "${key}" "${fingerprint}" "${generation}" "${FPF_IPC_FALLBACK_FILE:-}" "${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
2890
|
-
return
|
|
2891
|
-
fi
|
|
2892
|
-
|
|
2893
|
-
bun_run_refresh_worker "${manager}" "${query}" "${flags}" "${key}" "${fingerprint}" "${generation}" || true
|
|
2894
|
-
if [[ -s "${cache_file}" ]]; then
|
|
2895
|
-
cache_emit_query_rows_if_valid "${cache_file}" || true
|
|
2896
|
-
fi
|
|
2897
|
-
return
|
|
2898
|
-
fi
|
|
2899
|
-
|
|
2900
|
-
if [[ "${query_cache_enabled}" == "1" && -s "${cache_file}" ]]; then
|
|
2901
|
-
if [[ "${query_cache_ttl}" -eq 0 ]] || cache_is_fresh_with_ttl "${key}" "${query_cache_ttl}"; then
|
|
2902
|
-
cat "${cache_file}"
|
|
2903
|
-
return
|
|
2904
|
-
fi
|
|
2905
|
-
fi
|
|
2906
|
-
|
|
2907
|
-
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/query-cache.XXXXXX")"
|
|
2908
|
-
manager_search_entries_uncached "${manager}" "${query}" >"${output_tmp}" || true
|
|
2909
|
-
|
|
2910
|
-
if [[ "${query_cache_enabled}" == "1" ]]; then
|
|
2911
|
-
cache_store_key_from_file "${key}" "${fingerprint}" "${output_tmp}"
|
|
2912
|
-
fi
|
|
2913
|
-
|
|
2914
|
-
cat "${output_tmp}"
|
|
2915
|
-
rm -f "${output_tmp}"
|
|
2916
|
-
}
|
|
2917
|
-
|
|
2918
|
-
manager_installed_entries() {
|
|
2919
|
-
local manager="$1"
|
|
2920
|
-
|
|
2921
|
-
if [[ "${FPF_USE_GO_INSTALLED_ENTRIES:-0}" == "1" && -n "${FPF_SELF_PATH:-}" && -x "${FPF_SELF_PATH}" ]]; then
|
|
2922
|
-
"${FPF_SELF_PATH}" --go-installed-entries --go-manager "${manager}"
|
|
2923
|
-
return $?
|
|
2924
|
-
fi
|
|
2925
|
-
|
|
2926
|
-
case "${manager}" in
|
|
2927
|
-
apt)
|
|
2928
|
-
dpkg-query -W -f='${binary:Package}\t${Version}\n' 2>/dev/null
|
|
2929
|
-
;;
|
|
2930
|
-
dnf)
|
|
2931
|
-
dnf -q list installed 2>/dev/null |
|
|
2932
|
-
awk 'NR > 1 && $1 !~ /^(Installed|Last)/ { name=$1; sub(/\.[^.]+$/, "", name); print name "\t" $2 }'
|
|
2933
|
-
;;
|
|
2934
|
-
pacman)
|
|
2935
|
-
pacman -Q 2>/dev/null |
|
|
2936
|
-
awk '{ print $1 "\t" $2 }'
|
|
2937
|
-
;;
|
|
2938
|
-
zypper)
|
|
2939
|
-
zypper --non-interactive --quiet search --installed-only --details --type package 2>/dev/null |
|
|
2940
|
-
awk -F'|' '
|
|
2941
|
-
/^[[:space:]]*i[[:space:]]*\|/ {
|
|
2942
|
-
name=$3
|
|
2943
|
-
ver=$5
|
|
2944
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
|
2945
|
-
gsub(/^[[:space:]]+|[[:space:]]+$/, "", ver)
|
|
2946
|
-
if (name != "") print name "\t" ver
|
|
2947
|
-
}
|
|
2948
|
-
'
|
|
2949
|
-
;;
|
|
2950
|
-
emerge)
|
|
2951
|
-
if command_exists qlist; then
|
|
2952
|
-
qlist -ICv 2>/dev/null |
|
|
2953
|
-
awk '{ print $1 "\tinstalled" }'
|
|
2954
|
-
else
|
|
2955
|
-
local pkg_dir
|
|
2956
|
-
for pkg_dir in /var/db/pkg/*/*; do
|
|
2957
|
-
[[ -d "${pkg_dir}" ]] || continue
|
|
2958
|
-
printf "%s\tinstalled\n" "$(basename "${pkg_dir}")"
|
|
2959
|
-
done
|
|
2960
|
-
fi
|
|
2961
|
-
;;
|
|
2962
|
-
brew)
|
|
2963
|
-
brew list --versions 2>/dev/null |
|
|
2964
|
-
awk '{ name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="installed"; print name "\t" $0 }'
|
|
2965
|
-
;;
|
|
2966
|
-
winget)
|
|
2967
|
-
winget list --source winget --accept-source-agreements --disable-interactivity 2>/dev/null |
|
|
2968
|
-
awk '
|
|
2969
|
-
/^[[:space:]]*$/ { next }
|
|
2970
|
-
/^Name[[:space:]]+Id[[:space:]]+/ { next }
|
|
2971
|
-
/^[-[:space:]]+$/ { next }
|
|
2972
|
-
{
|
|
2973
|
-
line = $0
|
|
2974
|
-
sub(/^[[:space:]]+/, "", line)
|
|
2975
|
-
|
|
2976
|
-
pkg = ""
|
|
2977
|
-
ver = "installed"
|
|
2978
|
-
|
|
2979
|
-
n = split(line, cols, /[[:space:]][[:space:]]+/)
|
|
2980
|
-
if (n >= 2) {
|
|
2981
|
-
pkg = cols[2]
|
|
2982
|
-
}
|
|
2983
|
-
if (n >= 3 && cols[3] != "") {
|
|
2984
|
-
ver = cols[3]
|
|
2985
|
-
}
|
|
2986
|
-
|
|
2987
|
-
if (pkg != "") {
|
|
2988
|
-
print pkg "\t" ver
|
|
2989
|
-
}
|
|
2990
|
-
}
|
|
2991
|
-
'
|
|
2992
|
-
;;
|
|
2993
|
-
choco)
|
|
2994
|
-
choco list --local-only --limit-output 2>/dev/null |
|
|
2995
|
-
awk -F'|' 'NF >= 1 && $1 != "" { ver=$2; if (ver == "") ver="installed"; print $1 "\t" ver }'
|
|
2996
|
-
;;
|
|
2997
|
-
scoop)
|
|
2998
|
-
scoop list 2>/dev/null |
|
|
2999
|
-
awk '
|
|
3000
|
-
/^[[:space:]]*$/ { next }
|
|
3001
|
-
/^[-[:space:]]+$/ { next }
|
|
3002
|
-
/^Name[[:space:]]+/ { next }
|
|
3003
|
-
{
|
|
3004
|
-
ver = $2
|
|
3005
|
-
if (ver == "") ver = "installed"
|
|
3006
|
-
print $1 "\t" ver
|
|
3007
|
-
}
|
|
3008
|
-
'
|
|
3009
|
-
;;
|
|
3010
|
-
snap)
|
|
3011
|
-
snap list 2>/dev/null |
|
|
3012
|
-
awk 'NR > 1 { print $1 "\t" $2 }'
|
|
3013
|
-
;;
|
|
3014
|
-
flatpak)
|
|
3015
|
-
flatpak list --app --columns=application,version 2>/dev/null |
|
|
3016
|
-
awk 'NR > 1 { print $1 "\t" $2 }'
|
|
3017
|
-
;;
|
|
3018
|
-
npm)
|
|
3019
|
-
npm ls -g --depth=0 --parseable 2>/dev/null |
|
|
3020
|
-
awk '
|
|
3021
|
-
NR > 1 {
|
|
3022
|
-
line = $0
|
|
3023
|
-
gsub(/\r/, "", line)
|
|
3024
|
-
gsub(/\\/, "/", line)
|
|
3025
|
-
|
|
3026
|
-
n = split(line, parts, "/")
|
|
3027
|
-
if (n < 1) next
|
|
3028
|
-
|
|
3029
|
-
pkg = parts[n]
|
|
3030
|
-
if (pkg == "" && n > 1) pkg = parts[n - 1]
|
|
3031
|
-
if (pkg == "") next
|
|
3032
|
-
|
|
3033
|
-
if (n >= 2 && parts[n - 1] ~ /^@/) {
|
|
3034
|
-
pkg = parts[n - 1] "/" pkg
|
|
3035
|
-
}
|
|
3036
|
-
|
|
3037
|
-
print pkg "\tglobal"
|
|
3038
|
-
}
|
|
3039
|
-
'
|
|
3040
|
-
;;
|
|
3041
|
-
bun)
|
|
3042
|
-
{
|
|
3043
|
-
local bun_pm_file
|
|
3044
|
-
bun_pm_file="$(mktemp "${SESSION_TMP_ROOT}/bun-pm.XXXXXX")"
|
|
3045
|
-
if bun pm ls --global >"${bun_pm_file}" 2>/dev/null; then
|
|
3046
|
-
awk '
|
|
3047
|
-
NR > 1 {
|
|
3048
|
-
line = $0
|
|
3049
|
-
gsub(/\r/, "", line)
|
|
3050
|
-
sub(/^[[:space:]]*[^[:alnum:]@]*/, "", line)
|
|
3051
|
-
sub(/^[[:space:]]+/, "", line)
|
|
3052
|
-
sub(/[[:space:]]+$/, "", line)
|
|
3053
|
-
|
|
3054
|
-
if (line == "") next
|
|
3055
|
-
if (line ~ /[[:space:]]node_modules([[:space:]]|$)/) next
|
|
3056
|
-
|
|
3057
|
-
split(line, fields, /[[:space:]]+/)
|
|
3058
|
-
pkg = fields[1]
|
|
3059
|
-
if (pkg == "") next
|
|
3060
|
-
|
|
3061
|
-
pkg_copy = pkg
|
|
3062
|
-
at_count = gsub(/@/, "@", pkg_copy)
|
|
3063
|
-
if ((substr(pkg, 1, 1) == "@" && at_count >= 2) || (substr(pkg, 1, 1) != "@" && at_count >= 1)) {
|
|
3064
|
-
sub(/@[^@[:space:]]*$/, "", pkg)
|
|
3065
|
-
}
|
|
3066
|
-
|
|
3067
|
-
if (pkg != "") {
|
|
3068
|
-
print pkg "\tglobal"
|
|
3069
|
-
}
|
|
3070
|
-
}
|
|
3071
|
-
' "${bun_pm_file}"
|
|
3072
|
-
elif command_exists npm; then
|
|
3073
|
-
npm ls -g --depth=0 --parseable 2>/dev/null |
|
|
3074
|
-
awk '
|
|
3075
|
-
NR > 1 {
|
|
3076
|
-
line = $0
|
|
3077
|
-
gsub(/\r/, "", line)
|
|
3078
|
-
gsub(/\\/, "/", line)
|
|
3079
|
-
|
|
3080
|
-
n = split(line, parts, "/")
|
|
3081
|
-
if (n < 1) next
|
|
3082
|
-
|
|
3083
|
-
pkg = parts[n]
|
|
3084
|
-
if (pkg == "" && n > 1) pkg = parts[n - 1]
|
|
3085
|
-
if (pkg == "") next
|
|
3086
|
-
|
|
3087
|
-
if (n >= 2 && parts[n - 1] ~ /^@/) {
|
|
3088
|
-
pkg = parts[n - 1] "/" pkg
|
|
3089
|
-
}
|
|
3090
|
-
|
|
3091
|
-
print pkg "\tglobal"
|
|
3092
|
-
}
|
|
3093
|
-
'
|
|
3094
|
-
fi
|
|
3095
|
-
rm -f "${bun_pm_file}"
|
|
3096
|
-
} || true
|
|
3097
|
-
;;
|
|
3098
|
-
esac | sort -u || true
|
|
3099
|
-
}
|
|
3100
|
-
|
|
3101
|
-
manager_installed_names() {
|
|
3102
|
-
local manager="$1"
|
|
3103
|
-
manager_installed_entries "${manager}" | awk -F'\t' 'NF > 0 { print $1 }'
|
|
3104
|
-
}
|
|
3105
|
-
|
|
3106
|
-
installed_cache_ttl_seconds() {
|
|
3107
|
-
local ttl_seconds="${FPF_INSTALLED_CACHE_TTL:-300}"
|
|
3108
|
-
|
|
3109
|
-
if ! [[ "${ttl_seconds}" =~ ^[0-9]+$ ]]; then
|
|
3110
|
-
ttl_seconds="300"
|
|
3111
|
-
fi
|
|
3112
|
-
|
|
3113
|
-
printf "%s" "${ttl_seconds}"
|
|
3114
|
-
}
|
|
3115
|
-
|
|
3116
|
-
installed_cache_fingerprint() {
|
|
3117
|
-
local manager="$1"
|
|
3118
|
-
local command_path=""
|
|
3119
|
-
local extra_token=""
|
|
3120
|
-
|
|
3121
|
-
case "${manager}" in
|
|
3122
|
-
apt)
|
|
3123
|
-
command_path="$(command -v dpkg-query 2>/dev/null || printf "missing")"
|
|
3124
|
-
;;
|
|
3125
|
-
dnf)
|
|
3126
|
-
command_path="$(command -v dnf 2>/dev/null || printf "missing")"
|
|
3127
|
-
;;
|
|
3128
|
-
pacman)
|
|
3129
|
-
command_path="$(command -v pacman 2>/dev/null || printf "missing")"
|
|
3130
|
-
;;
|
|
3131
|
-
zypper)
|
|
3132
|
-
command_path="$(command -v zypper 2>/dev/null || printf "missing")"
|
|
3133
|
-
;;
|
|
3134
|
-
emerge)
|
|
3135
|
-
if command_exists qlist; then
|
|
3136
|
-
command_path="$(command -v qlist 2>/dev/null || printf "missing")"
|
|
3137
|
-
extra_token="|mode=qlist"
|
|
3138
|
-
else
|
|
3139
|
-
command_path="/var/db/pkg"
|
|
3140
|
-
extra_token="|mode=vardb"
|
|
3141
|
-
fi
|
|
3142
|
-
;;
|
|
3143
|
-
brew)
|
|
3144
|
-
command_path="$(command -v brew 2>/dev/null || printf "missing")"
|
|
3145
|
-
;;
|
|
3146
|
-
winget)
|
|
3147
|
-
command_path="$(command -v winget 2>/dev/null || printf "missing")"
|
|
3148
|
-
;;
|
|
3149
|
-
choco)
|
|
3150
|
-
command_path="$(command -v choco 2>/dev/null || printf "missing")"
|
|
3151
|
-
;;
|
|
3152
|
-
scoop)
|
|
3153
|
-
command_path="$(command -v scoop 2>/dev/null || printf "missing")"
|
|
3154
|
-
;;
|
|
3155
|
-
snap)
|
|
3156
|
-
command_path="$(command -v snap 2>/dev/null || printf "missing")"
|
|
3157
|
-
;;
|
|
3158
|
-
flatpak)
|
|
3159
|
-
command_path="$(command -v flatpak 2>/dev/null || printf "missing")"
|
|
3160
|
-
;;
|
|
3161
|
-
npm)
|
|
3162
|
-
command_path="$(command -v npm 2>/dev/null || printf "missing")"
|
|
3163
|
-
;;
|
|
3164
|
-
bun)
|
|
3165
|
-
command_path="$(command -v bun 2>/dev/null || printf "missing")"
|
|
3166
|
-
if command_exists npm; then
|
|
3167
|
-
extra_token="|npm=$(command -v npm 2>/dev/null || printf "missing")"
|
|
3168
|
-
fi
|
|
3169
|
-
;;
|
|
3170
|
-
*)
|
|
3171
|
-
command_path="unknown"
|
|
3172
|
-
;;
|
|
3173
|
-
esac
|
|
3174
|
-
|
|
3175
|
-
printf "%s|cmd=%s%s" "$(cache_fingerprint "${manager}" "" "installed")" "${command_path}" "${extra_token}"
|
|
3176
|
-
}
|
|
3177
|
-
|
|
3178
|
-
manager_installed_names_cached() {
|
|
3179
|
-
local manager="$1"
|
|
3180
|
-
local output_file="$2"
|
|
3181
|
-
local cache_enabled="${FPF_DISABLE_INSTALLED_CACHE:-0}"
|
|
3182
|
-
local cache_ttl_seconds
|
|
3183
|
-
local cache_key
|
|
3184
|
-
local cache_file
|
|
3185
|
-
local cache_fingerprint_value
|
|
3186
|
-
local cached_fingerprint=""
|
|
3187
|
-
|
|
3188
|
-
initialize_cache_root
|
|
3189
|
-
|
|
3190
|
-
cache_key="$(cache_catalog_key "${manager}")"
|
|
3191
|
-
cache_file="$(cache_path_for_key "${cache_key}")"
|
|
3192
|
-
cache_ttl_seconds="$(installed_cache_ttl_seconds)"
|
|
3193
|
-
cache_fingerprint_value="$(installed_cache_fingerprint "${manager}")"
|
|
3194
|
-
|
|
3195
|
-
if [[ "${cache_enabled}" != "1" && -s "${cache_file}" ]]; then
|
|
3196
|
-
cached_fingerprint="$(cache_meta_value_for_key "${cache_key}" "fingerprint" 2>/dev/null || true)"
|
|
3197
|
-
if [[ "${cached_fingerprint}" == "${cache_fingerprint_value}" ]] && cache_is_fresh_with_ttl "${cache_key}" "${cache_ttl_seconds}"; then
|
|
3198
|
-
cp "${cache_file}" "${output_file}"
|
|
3199
|
-
return
|
|
3200
|
-
fi
|
|
3201
|
-
fi
|
|
3202
|
-
|
|
3203
|
-
manager_installed_names "${manager}" >"${output_file}" 2>/dev/null || true
|
|
3204
|
-
|
|
3205
|
-
if [[ "${cache_enabled}" != "1" && -s "${output_file}" ]]; then
|
|
3206
|
-
cache_store_key_from_file "${cache_key}" "${cache_fingerprint_value}" "${output_file}"
|
|
3207
|
-
fi
|
|
3208
|
-
}
|
|
3209
|
-
|
|
3210
|
-
mark_installed_packages() {
|
|
3211
|
-
local source_file="$1"
|
|
3212
|
-
local output_file="$2"
|
|
3213
|
-
local unique_managers_file
|
|
3214
|
-
local manager_counts_file
|
|
3215
|
-
local installed_file
|
|
3216
|
-
local installed_map_file
|
|
3217
|
-
local installed_part_file
|
|
3218
|
-
local manager_match_count
|
|
3219
|
-
local installed_match_count
|
|
3220
|
-
local installed_part_files=()
|
|
3221
|
-
local gather_pids=()
|
|
3222
|
-
local manager
|
|
3223
|
-
local gather_pid
|
|
3224
|
-
|
|
3225
|
-
unique_managers_file="$(mktemp "${SESSION_TMP_ROOT}/installed-managers.XXXXXX")"
|
|
3226
|
-
awk -F'\t' 'NF >= 1 && $1 != "" { print $1 }' "${source_file}" | awk '!seen[$0]++' >"${unique_managers_file}"
|
|
3227
|
-
|
|
3228
|
-
manager_counts_file="$(mktemp "${SESSION_TMP_ROOT}/installed-counts.XXXXXX")"
|
|
3229
|
-
awk -F'\t' 'NF >= 1 && $1 != "" { counts[$1]++ } END { for (mgr in counts) print mgr "\t" counts[mgr] }' "${source_file}" >"${manager_counts_file}"
|
|
3230
|
-
|
|
3231
|
-
if [[ "${FPF_SKIP_INSTALLED_MARKERS:-0}" == "1" ]]; then
|
|
3232
|
-
awk -F'\t' '
|
|
3233
|
-
{
|
|
3234
|
-
desc = $3
|
|
3235
|
-
if (desc == "") desc = "-"
|
|
3236
|
-
print $1 "\t" $2 "\t " desc
|
|
3237
|
-
}
|
|
3238
|
-
' "${source_file}" >"${output_file}"
|
|
3239
|
-
while IFS= read -r manager; do
|
|
3240
|
-
[[ -n "${manager}" ]] || continue
|
|
3241
|
-
loading_progress_mark_done "${manager}" "installed marker check skipped"
|
|
3242
|
-
done <"${unique_managers_file}"
|
|
3243
|
-
rm -f "${unique_managers_file}" "${manager_counts_file}"
|
|
3244
|
-
return
|
|
3245
|
-
fi
|
|
3246
|
-
|
|
3247
|
-
installed_map_file="$(mktemp "${SESSION_TMP_ROOT}/installed-map.XXXXXX")"
|
|
3248
|
-
: >"${installed_map_file}"
|
|
3249
|
-
|
|
3250
|
-
while IFS= read -r manager; do
|
|
3251
|
-
[[ -n "${manager}" ]] || continue
|
|
3252
|
-
installed_part_file="$(mktemp "${SESSION_TMP_ROOT}/installed-map.${manager}.XXXXXX")"
|
|
3253
|
-
installed_part_files+=("${installed_part_file}")
|
|
3254
|
-
|
|
3255
|
-
(
|
|
3256
|
-
manager_match_count="$(awk -F'\t' -v mgr="${manager}" '$1 == mgr { print $2; found=1; exit } END { if (!found) print 0 }' "${manager_counts_file}")"
|
|
3257
|
-
if ! [[ "${manager_match_count}" =~ ^[0-9]+$ ]]; then
|
|
3258
|
-
manager_match_count=0
|
|
3259
|
-
fi
|
|
3260
|
-
|
|
3261
|
-
loading_progress_mark_running "${manager}" "mark installed (${manager_match_count})"
|
|
3262
|
-
installed_file="$(mktemp "${SESSION_TMP_ROOT}/installed.${manager}.XXXXXX")"
|
|
3263
|
-
manager_installed_names_cached "${manager}" "${installed_file}" || true
|
|
3264
|
-
installed_match_count=0
|
|
3265
|
-
if [[ -s "${installed_file}" ]]; then
|
|
3266
|
-
awk -F'\t' -v mgr="${manager}" 'NF > 0 && $1 != "" { print mgr "\t" $1 }' "${installed_file}" >"${installed_part_file}"
|
|
3267
|
-
installed_match_count="$(awk 'END { print NR + 0 }' "${installed_part_file}")"
|
|
3268
|
-
fi
|
|
3269
|
-
rm -f "${installed_file}"
|
|
3270
|
-
loading_progress_mark_done "${manager}" "${manager_match_count} matches, ${installed_match_count} installed"
|
|
3271
|
-
) &
|
|
3272
|
-
gather_pids+=("$!")
|
|
3273
|
-
done <"${unique_managers_file}"
|
|
3274
|
-
|
|
3275
|
-
for gather_pid in "${gather_pids[@]-}"; do
|
|
3276
|
-
wait "${gather_pid}" || true
|
|
3277
|
-
done
|
|
3278
|
-
|
|
3279
|
-
for installed_part_file in "${installed_part_files[@]-}"; do
|
|
3280
|
-
if [[ -s "${installed_part_file}" ]]; then
|
|
3281
|
-
cat "${installed_part_file}" >>"${installed_map_file}"
|
|
3282
|
-
fi
|
|
3283
|
-
rm -f "${installed_part_file}"
|
|
3284
|
-
done
|
|
3285
|
-
|
|
3286
|
-
awk -F'\t' '
|
|
3287
|
-
FILENAME == ARGV[1] {
|
|
3288
|
-
key = $1 "\t" $2
|
|
3289
|
-
if ($1 != "" && $2 != "") {
|
|
3290
|
-
installed[key] = 1
|
|
3291
|
-
}
|
|
3292
|
-
next
|
|
3293
|
-
}
|
|
3294
|
-
{
|
|
3295
|
-
key = $1 "\t" $2
|
|
3296
|
-
mark = (installed[key] ? "* " : " ")
|
|
3297
|
-
desc = $3
|
|
3298
|
-
if (desc == "") desc = "-"
|
|
3299
|
-
print $1 "\t" $2 "\t" mark desc
|
|
3300
|
-
}
|
|
3301
|
-
' "${installed_map_file}" "${source_file}" >"${output_file}"
|
|
3302
|
-
|
|
3303
|
-
rm -f "${unique_managers_file}" "${manager_counts_file}"
|
|
3304
|
-
rm -f "${installed_map_file}"
|
|
3305
|
-
}
|
|
3306
|
-
|
|
3307
|
-
merge_search_display_rows() {
|
|
3308
|
-
local source_file="$1"
|
|
3309
|
-
local output_file="$2"
|
|
3310
|
-
|
|
3311
|
-
if [[ "${FPF_USE_GO_DISPLAY_PIPELINE:-0}" == "1" && -n "${FPF_SELF_PATH:-}" && -x "${FPF_SELF_PATH}" ]]; then
|
|
3312
|
-
"${FPF_SELF_PATH}" --go-merge-display --go-source "${source_file}" --go-output "${output_file}"
|
|
3313
|
-
return $?
|
|
3314
|
-
fi
|
|
3315
|
-
|
|
3316
|
-
if [[ ! -s "${source_file}" ]]; then
|
|
3317
|
-
: >"${output_file}"
|
|
3318
|
-
return
|
|
3319
|
-
fi
|
|
3320
|
-
|
|
3321
|
-
sort -t $'\t' -k1,1 -k2,2 -k3,3 "${source_file}" |
|
|
3322
|
-
awk -F'\t' '
|
|
3323
|
-
NF >= 2 {
|
|
3324
|
-
key = $1 "\t" $2
|
|
3325
|
-
if (seen[key]++) {
|
|
3326
|
-
next
|
|
3327
|
-
}
|
|
3328
|
-
desc = $3
|
|
3329
|
-
if (desc == "") desc = "-"
|
|
3330
|
-
print $1 "\t" $2 "\t" desc
|
|
3331
|
-
}
|
|
3332
|
-
' >"${output_file}"
|
|
3333
|
-
}
|
|
3334
|
-
|
|
3335
|
-
collect_search_display_rows() {
|
|
3336
|
-
local query="$1"
|
|
3337
|
-
local output_file="$2"
|
|
3338
|
-
shift 2
|
|
3339
|
-
local managers=("$@")
|
|
3340
|
-
local managers_csv=""
|
|
3341
|
-
local query_limit="${FPF_QUERY_RESULT_LIMIT:-0}"
|
|
3342
|
-
|
|
3343
|
-
if [[ "${FPF_USE_GO_DISPLAY_PIPELINE:-0}" == "1" && -n "${FPF_SELF_PATH:-}" && -x "${FPF_SELF_PATH}" ]]; then
|
|
3344
|
-
managers_csv="$(IFS=','; printf '%s' "${managers[*]-}")"
|
|
3345
|
-
if "${FPF_SELF_PATH}" --go-build-display --go-query "${query}" --go-output "${output_file}" --go-managers "${managers_csv}"; then
|
|
3346
|
-
return 0
|
|
3347
|
-
fi
|
|
3348
|
-
fi
|
|
3349
|
-
|
|
3350
|
-
: >"${output_file}"
|
|
3351
|
-
|
|
3352
|
-
local part_files=()
|
|
3353
|
-
local gather_pids=()
|
|
3354
|
-
local manager
|
|
3355
|
-
local part_file
|
|
3356
|
-
local gather_pid
|
|
3357
|
-
local merged_source_file
|
|
3358
|
-
local merged_marked_file
|
|
3359
|
-
|
|
3360
|
-
for manager in "${managers[@]-}"; do
|
|
3361
|
-
part_file="$(mktemp "${SESSION_TMP_ROOT}/part.XXXXXX")"
|
|
3362
|
-
part_files+=("${part_file}")
|
|
3363
|
-
|
|
3364
|
-
(
|
|
3365
|
-
local local_source_file
|
|
3366
|
-
local result_count=0
|
|
3367
|
-
|
|
3368
|
-
loading_progress_mark_running "${manager}" "query index"
|
|
3369
|
-
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
3370
|
-
manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
|
|
3371
|
-
if [[ -s "${local_source_file}" ]]; then
|
|
3372
|
-
awk -F'\t' -v mgr="${manager}" '
|
|
3373
|
-
NF >= 1 {
|
|
3374
|
-
desc = $2
|
|
3375
|
-
if (desc == "") desc = "-"
|
|
3376
|
-
print mgr "\t" $1 "\t" desc
|
|
3377
|
-
}
|
|
3378
|
-
' "${local_source_file}" >"${part_file}"
|
|
3379
|
-
fi
|
|
3380
|
-
rm -f "${local_source_file}"
|
|
3381
|
-
|
|
3382
|
-
if [[ -s "${part_file}" ]]; then
|
|
3383
|
-
result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
|
|
3384
|
-
fi
|
|
3385
|
-
loading_progress_mark_running "${manager}" "${result_count} indexed; mark installed"
|
|
3386
|
-
) &
|
|
3387
|
-
gather_pids+=("$!")
|
|
3388
|
-
done
|
|
3389
|
-
|
|
3390
|
-
for gather_pid in "${gather_pids[@]-}"; do
|
|
3391
|
-
wait "${gather_pid}" || true
|
|
3392
|
-
done
|
|
3393
|
-
|
|
3394
|
-
merged_source_file="$(mktemp "${SESSION_TMP_ROOT}/merged-source.XXXXXX")"
|
|
3395
|
-
merged_marked_file="$(mktemp "${SESSION_TMP_ROOT}/merged-marked.XXXXXX")"
|
|
3396
|
-
|
|
3397
|
-
for part_file in "${part_files[@]-}"; do
|
|
3398
|
-
if [[ -s "${part_file}" ]]; then
|
|
3399
|
-
cat "${part_file}" >>"${merged_source_file}"
|
|
3400
|
-
fi
|
|
3401
|
-
rm -f "${part_file}"
|
|
3402
|
-
done
|
|
3403
|
-
|
|
3404
|
-
if [[ -s "${merged_source_file}" ]]; then
|
|
3405
|
-
merge_search_display_rows "${merged_source_file}" "${merged_marked_file}"
|
|
3406
|
-
mark_installed_packages "${merged_marked_file}" "${output_file}"
|
|
3407
|
-
rank_display_rows_by_query "${query}" "${output_file}"
|
|
3408
|
-
|
|
3409
|
-
if [[ -n "${query}" && "${query_limit}" =~ ^[0-9]+$ && "${query_limit}" -gt 0 ]]; then
|
|
3410
|
-
awk -v limit="${query_limit}" 'NR <= limit' "${output_file}" >"${output_file}.limited"
|
|
3411
|
-
mv "${output_file}.limited" "${output_file}"
|
|
3412
|
-
fi
|
|
3413
|
-
else
|
|
3414
|
-
for manager in "${managers[@]-}"; do
|
|
3415
|
-
loading_progress_mark_done "${manager}" "0 packages matched"
|
|
3416
|
-
done
|
|
3417
|
-
fi
|
|
3418
|
-
|
|
3419
|
-
rm -f "${merged_source_file}" "${merged_marked_file}"
|
|
3420
|
-
}
|
|
3421
|
-
|
|
3422
|
-
collect_installed_display_rows() {
|
|
3423
|
-
local output_file="$1"
|
|
3424
|
-
shift
|
|
3425
|
-
local managers=("$@")
|
|
3426
|
-
local part_files=()
|
|
3427
|
-
local gather_pids=()
|
|
3428
|
-
local manager
|
|
3429
|
-
local part_file
|
|
3430
|
-
local gather_pid
|
|
3431
|
-
|
|
3432
|
-
: >"${output_file}"
|
|
3433
|
-
|
|
3434
|
-
for manager in "${managers[@]-}"; do
|
|
3435
|
-
part_file="$(mktemp "${SESSION_TMP_ROOT}/part.XXXXXX")"
|
|
3436
|
-
part_files+=("${part_file}")
|
|
3437
|
-
|
|
3438
|
-
(
|
|
3439
|
-
local local_source_file
|
|
3440
|
-
local result_count=0
|
|
3441
|
-
|
|
3442
|
-
loading_progress_mark_running "${manager}" "read installed"
|
|
3443
|
-
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
3444
|
-
manager_installed_entries "${manager}" >"${local_source_file}" || true
|
|
3445
|
-
if [[ -s "${local_source_file}" ]]; then
|
|
3446
|
-
awk -F'\t' -v mgr="${manager}" '
|
|
3447
|
-
NF >= 1 {
|
|
3448
|
-
desc = $2
|
|
3449
|
-
if (desc == "") desc = "-"
|
|
3450
|
-
print mgr "\t" $1 "\t" desc
|
|
3451
|
-
}
|
|
3452
|
-
' "${local_source_file}" >"${part_file}"
|
|
3453
|
-
fi
|
|
3454
|
-
rm -f "${local_source_file}"
|
|
3455
|
-
|
|
3456
|
-
if [[ -s "${part_file}" ]]; then
|
|
3457
|
-
result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
|
|
3458
|
-
fi
|
|
3459
|
-
loading_progress_mark_done "${manager}" "${result_count} installed packages"
|
|
3460
|
-
) &
|
|
3461
|
-
gather_pids+=("$!")
|
|
3462
|
-
done
|
|
3463
|
-
|
|
3464
|
-
for gather_pid in "${gather_pids[@]-}"; do
|
|
3465
|
-
wait "${gather_pid}" || true
|
|
3466
|
-
done
|
|
3467
|
-
|
|
3468
|
-
for part_file in "${part_files[@]-}"; do
|
|
3469
|
-
if [[ -s "${part_file}" ]]; then
|
|
3470
|
-
cat "${part_file}" >>"${output_file}"
|
|
3471
|
-
fi
|
|
3472
|
-
rm -f "${part_file}"
|
|
3473
|
-
done
|
|
3474
|
-
|
|
3475
|
-
if [[ -s "${output_file}" ]]; then
|
|
3476
|
-
sort -u "${output_file}" -o "${output_file}"
|
|
3477
|
-
fi
|
|
3478
|
-
}
|
|
3479
|
-
|
|
3480
|
-
build_dynamic_reload_command() {
|
|
3481
|
-
local manager_override="$1"
|
|
3482
|
-
local fallback_file="$2"
|
|
3483
|
-
local manager_list_csv="${3:-}"
|
|
3484
|
-
local script_path="$(invocation_script_path)"
|
|
3485
|
-
local bypass_query_cache="1"
|
|
3486
|
-
|
|
3487
|
-
bypass_query_cache="$(dynamic_reload_query_cache_bypass_value)"
|
|
3488
|
-
|
|
3489
|
-
printf 'FPF_SKIP_INSTALLED_MARKERS=1 FPF_BYPASS_QUERY_CACHE=%s FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_MANAGER_LIST=%q FPF_IPC_FALLBACK_FILE=%q %q --dynamic-reload -- "{q}"' "${bypass_query_cache}" "${manager_override}" "${manager_list_csv}" "${fallback_file}" "${script_path}"
|
|
3490
|
-
}
|
|
3491
|
-
|
|
3492
|
-
build_dynamic_reload_command_for_query() {
|
|
3493
|
-
local manager_override="$1"
|
|
3494
|
-
local fallback_file="$2"
|
|
3495
|
-
local manager_list_csv="$3"
|
|
3496
|
-
local query_value="$4"
|
|
3497
|
-
local script_path="$(invocation_script_path)"
|
|
3498
|
-
local bypass_query_cache="1"
|
|
3499
|
-
|
|
3500
|
-
bypass_query_cache="$(dynamic_reload_query_cache_bypass_value)"
|
|
3501
|
-
|
|
3502
|
-
printf 'FPF_SKIP_INSTALLED_MARKERS=1 FPF_BYPASS_QUERY_CACHE=%s FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_MANAGER_LIST=%q FPF_IPC_FALLBACK_FILE=%q %q --dynamic-reload -- %q' "${bypass_query_cache}" "${manager_override}" "${manager_list_csv}" "${fallback_file}" "${script_path}" "${query_value}"
|
|
3503
|
-
}
|
|
3504
|
-
|
|
3505
|
-
build_dynamic_reload_ipc_command() {
|
|
3506
|
-
local manager_override="$1"
|
|
3507
|
-
local fallback_file="$2"
|
|
3508
|
-
local manager_list_csv="${3:-}"
|
|
3509
|
-
local script_path="$(invocation_script_path)"
|
|
3510
|
-
|
|
3511
|
-
printf 'FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_MANAGER_LIST=%q FPF_IPC_FALLBACK_FILE=%q %q --ipc-reload -- "{q}"' "${manager_override}" "${manager_list_csv}" "${fallback_file}" "${script_path}"
|
|
3512
|
-
}
|
|
3513
|
-
|
|
3514
|
-
build_dynamic_query_notify_ipc_command() {
|
|
3515
|
-
local manager_override="$1"
|
|
3516
|
-
local fallback_file="$2"
|
|
3517
|
-
local manager_list_csv="${3:-}"
|
|
3518
|
-
local script_path="$(invocation_script_path)"
|
|
3519
|
-
|
|
3520
|
-
printf 'FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_MANAGER_LIST=%q FPF_IPC_FALLBACK_FILE=%q %q --ipc-query-notify -- "{q}"' "${manager_override}" "${manager_list_csv}" "${fallback_file}" "${script_path}"
|
|
3521
|
-
}
|
|
3522
|
-
|
|
3523
|
-
fzf_supports_listen() {
|
|
3524
|
-
local fzf_help
|
|
3525
|
-
fzf_help="$(fzf --help 2>&1 || true)"
|
|
3526
|
-
[[ "${fzf_help}" == *"--listen"* ]]
|
|
3527
|
-
}
|
|
3528
|
-
|
|
3529
|
-
fzf_supports_result_bind() {
|
|
3530
|
-
if [[ -n "${FPF_FZF_RESULT_BIND_SUPPORTED_CACHE:-}" ]]; then
|
|
3531
|
-
[[ "${FPF_FZF_RESULT_BIND_SUPPORTED_CACHE}" == "1" ]]
|
|
3532
|
-
return
|
|
3533
|
-
fi
|
|
3534
|
-
|
|
3535
|
-
local probe_output=""
|
|
3536
|
-
probe_output="$(printf 'probe\n' | fzf --bind='result:abort' --filter probe 2>&1 >/dev/null || true)"
|
|
3537
|
-
|
|
3538
|
-
if [[ "${probe_output}" == *"unsupported key: result"* ]]; then
|
|
3539
|
-
FPF_FZF_RESULT_BIND_SUPPORTED_CACHE="0"
|
|
3540
|
-
return 1
|
|
3541
|
-
fi
|
|
3542
|
-
|
|
3543
|
-
FPF_FZF_RESULT_BIND_SUPPORTED_CACHE="1"
|
|
3544
|
-
return 0
|
|
3545
|
-
}
|
|
3546
|
-
|
|
3547
|
-
send_fzf_listen_action() {
|
|
3548
|
-
local action_payload="$1"
|
|
3549
|
-
local listen_target="${FZF_PORT:-}"
|
|
3550
|
-
local host="127.0.0.1"
|
|
3551
|
-
local port=""
|
|
3552
|
-
local payload_size
|
|
3553
|
-
|
|
3554
|
-
if [[ "${listen_target}" =~ ^[0-9]+$ ]]; then
|
|
3555
|
-
port="${listen_target}"
|
|
3556
|
-
elif [[ "${listen_target}" =~ ^([^:]+):([0-9]+)$ ]]; then
|
|
3557
|
-
host="${BASH_REMATCH[1]}"
|
|
3558
|
-
port="${BASH_REMATCH[2]}"
|
|
3559
|
-
elif [[ "${listen_target}" =~ ^https?://([^:/]+):([0-9]+)$ ]]; then
|
|
3560
|
-
host="${BASH_REMATCH[1]}"
|
|
3561
|
-
port="${BASH_REMATCH[2]}"
|
|
3562
|
-
elif [[ "${listen_target}" =~ ^\[([^]]+)\]:([0-9]+)$ ]]; then
|
|
3563
|
-
host="${BASH_REMATCH[1]}"
|
|
3564
|
-
port="${BASH_REMATCH[2]}"
|
|
3565
|
-
fi
|
|
3566
|
-
|
|
3567
|
-
if [[ -z "${port}" ]] || ! [[ "${port}" =~ ^[0-9]+$ ]] || [[ "${port}" -le 0 || "${port}" -gt 65535 ]]; then
|
|
3568
|
-
return 1
|
|
3569
|
-
fi
|
|
3570
|
-
|
|
3571
|
-
if [[ "${host}" == "0.0.0.0" || "${host}" == "*" ]]; then
|
|
3572
|
-
host="127.0.0.1"
|
|
3573
|
-
fi
|
|
3574
|
-
|
|
3575
|
-
payload_size="$(printf "%s" "${action_payload}" | wc -c | tr -d '[:space:]')"
|
|
3576
|
-
|
|
3577
|
-
if command_exists curl; then
|
|
3578
|
-
if curl --silent --show-error --fail --max-time 2 \
|
|
3579
|
-
--request POST \
|
|
3580
|
-
--header 'Content-Type: text/plain' \
|
|
3581
|
-
--data-binary "${action_payload}" \
|
|
3582
|
-
"http://${host}:${port}" >/dev/null 2>&1; then
|
|
3583
|
-
return 0
|
|
3584
|
-
fi
|
|
3585
|
-
fi
|
|
3586
|
-
|
|
3587
|
-
if command_exists nc; then
|
|
3588
|
-
if {
|
|
3589
|
-
printf 'POST / HTTP/1.1\r\n'
|
|
3590
|
-
printf 'Host: %s:%s\r\n' "${host}" "${port}"
|
|
3591
|
-
printf 'Content-Type: text/plain\r\n'
|
|
3592
|
-
printf 'Content-Length: %s\r\n' "${payload_size}"
|
|
3593
|
-
printf '\r\n'
|
|
3594
|
-
printf '%s' "${action_payload}"
|
|
3595
|
-
} | nc -w 2 "${host}" "${port}" >/dev/null 2>&1; then
|
|
3596
|
-
return 0
|
|
3597
|
-
fi
|
|
3598
|
-
fi
|
|
3599
|
-
|
|
3600
|
-
if exec 9<>"/dev/tcp/${host}/${port}" 2>/dev/null; then
|
|
3601
|
-
printf 'POST / HTTP/1.1\r\n' >&9
|
|
3602
|
-
printf 'Host: %s:%s\r\n' "${host}" "${port}" >&9
|
|
3603
|
-
printf 'Content-Type: text/plain\r\n' >&9
|
|
3604
|
-
printf 'Content-Length: %s\r\n' "${payload_size}" >&9
|
|
3605
|
-
printf '\r\n' >&9
|
|
3606
|
-
printf '%s' "${action_payload}" >&9
|
|
3607
|
-
exec 9>&-
|
|
3608
|
-
return 0
|
|
3609
|
-
fi
|
|
3610
|
-
|
|
3611
|
-
return 1
|
|
3612
|
-
}
|
|
3613
|
-
|
|
3614
|
-
send_fzf_prompt_action() {
|
|
3615
|
-
local prompt_text="$1"
|
|
3616
|
-
local action_payload
|
|
3617
|
-
|
|
3618
|
-
action_payload="change-prompt(${prompt_text})"
|
|
3619
|
-
send_fzf_listen_action "${action_payload}"
|
|
3620
|
-
}
|
|
3621
|
-
|
|
3622
|
-
run_dynamic_reload_action() {
|
|
3623
|
-
local query="$1"
|
|
3624
|
-
local manager_override="${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
3625
|
-
local manager_list_csv="${FPF_IPC_MANAGER_LIST:-}"
|
|
3626
|
-
local fallback_file="${FPF_IPC_FALLBACK_FILE:-}"
|
|
3627
|
-
local min_chars="${FPF_RELOAD_MIN_CHARS:-2}"
|
|
3628
|
-
local reload_debounce="${FPF_RELOAD_DEBOUNCE:-0.12}"
|
|
3629
|
-
local output_file=""
|
|
3630
|
-
local detected_manager=""
|
|
3631
|
-
local manager_seen=""
|
|
3632
|
-
local manager_entry=""
|
|
3633
|
-
local -a manager_list_entries=()
|
|
3634
|
-
local -a managers=()
|
|
3635
|
-
|
|
3636
|
-
if [[ -z "${fallback_file}" || ! -r "${fallback_file}" ]]; then
|
|
3637
|
-
return 1
|
|
3638
|
-
fi
|
|
3639
|
-
|
|
3640
|
-
if ! [[ "${min_chars}" =~ ^[0-9]+$ ]]; then
|
|
3641
|
-
min_chars=2
|
|
3642
|
-
fi
|
|
3643
|
-
|
|
3644
|
-
if ! [[ "${reload_debounce}" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
3645
|
-
reload_debounce=0.12
|
|
3646
|
-
fi
|
|
3647
|
-
|
|
3648
|
-
if [[ ${#query} -lt ${min_chars} ]]; then
|
|
3649
|
-
cat "${fallback_file}"
|
|
3650
|
-
return 0
|
|
3651
|
-
fi
|
|
3652
|
-
|
|
3653
|
-
sleep "${reload_debounce}"
|
|
3654
|
-
|
|
3655
|
-
if [[ -n "${manager_override}" ]]; then
|
|
3656
|
-
manager_override="$(normalize_manager "${manager_override}")"
|
|
3657
|
-
if ! manager_supported "${manager_override}" || ! manager_command_ready "${manager_override}"; then
|
|
3658
|
-
cat "${fallback_file}"
|
|
3659
|
-
return 0
|
|
3660
|
-
fi
|
|
3661
|
-
managers+=("${manager_override}")
|
|
3662
|
-
elif [[ -n "${manager_list_csv}" ]]; then
|
|
3663
|
-
IFS=',' read -r -a manager_list_entries <<<"${manager_list_csv}"
|
|
3664
|
-
for manager_entry in "${manager_list_entries[@]-}"; do
|
|
3665
|
-
manager_entry="$(trim_whitespace "${manager_entry}")"
|
|
3666
|
-
[[ -n "${manager_entry}" ]] || continue
|
|
3667
|
-
|
|
3668
|
-
detected_manager="$(normalize_manager "${manager_entry}")"
|
|
3669
|
-
if ! manager_supported "${detected_manager}" || ! manager_command_ready "${detected_manager}"; then
|
|
3670
|
-
continue
|
|
3671
|
-
fi
|
|
3672
|
-
|
|
3673
|
-
case " ${manager_seen} " in
|
|
3674
|
-
*" ${detected_manager} "*)
|
|
3675
|
-
continue
|
|
3676
|
-
;;
|
|
3677
|
-
esac
|
|
3678
|
-
manager_seen+=" ${detected_manager}"
|
|
3679
|
-
managers+=("${detected_manager}")
|
|
3680
|
-
done
|
|
3681
|
-
else
|
|
3682
|
-
while IFS= read -r detected_manager; do
|
|
3683
|
-
[[ -n "${detected_manager}" ]] || continue
|
|
3684
|
-
if manager_supported "${detected_manager}" && manager_command_ready "${detected_manager}"; then
|
|
3685
|
-
managers+=("${detected_manager}")
|
|
3686
|
-
fi
|
|
3687
|
-
done < <(detect_default_managers)
|
|
3688
|
-
fi
|
|
3689
|
-
|
|
3690
|
-
if [[ "${#managers[@]}" -eq 0 ]]; then
|
|
3691
|
-
cat "${fallback_file}"
|
|
3692
|
-
return 0
|
|
3693
|
-
fi
|
|
3694
|
-
|
|
3695
|
-
output_file="$(mktemp "${SESSION_TMP_ROOT}/dynamic-reload.XXXXXX")"
|
|
3696
|
-
: >"${output_file}"
|
|
3697
|
-
|
|
3698
|
-
if collect_search_display_rows "${query}" "${output_file}" "${managers[@]-}"; then
|
|
3699
|
-
cat "${output_file}"
|
|
3700
|
-
else
|
|
3701
|
-
cat "${fallback_file}"
|
|
3702
|
-
fi
|
|
3703
|
-
|
|
3704
|
-
rm -f "${output_file}"
|
|
3705
|
-
}
|
|
3706
|
-
|
|
3707
|
-
run_ipc_reload_action() {
|
|
3708
|
-
local query="$1"
|
|
3709
|
-
local manager_override="${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
3710
|
-
local manager_list_csv="${FPF_IPC_MANAGER_LIST:-}"
|
|
3711
|
-
local fallback_file="${FPF_IPC_FALLBACK_FILE:-}"
|
|
3712
|
-
local reload_command
|
|
3713
|
-
local action_payload
|
|
3714
|
-
|
|
3715
|
-
if [[ -z "${fallback_file}" || ! -r "${fallback_file}" ]]; then
|
|
3716
|
-
return 1
|
|
3717
|
-
fi
|
|
3718
|
-
|
|
3719
|
-
if [[ -n "${manager_override}" ]]; then
|
|
3720
|
-
manager_override="$(normalize_manager "${manager_override}")"
|
|
3721
|
-
manager_supported "${manager_override}" || return 1
|
|
3722
|
-
fi
|
|
3723
|
-
|
|
3724
|
-
reload_command="$(build_dynamic_reload_command_for_query "${manager_override}" "${fallback_file}" "${manager_list_csv}" "${query}")"
|
|
3725
|
-
action_payload="change-prompt(Search> )+reload(${reload_command})"
|
|
3726
|
-
send_fzf_listen_action "${action_payload}"
|
|
3727
|
-
}
|
|
3728
|
-
|
|
3729
|
-
run_ipc_query_notify_action() {
|
|
3730
|
-
local query="$1"
|
|
3731
|
-
local manager_override="${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
3732
|
-
local fallback_file="${FPF_IPC_FALLBACK_FILE:-}"
|
|
3733
|
-
local min_chars="${FPF_RELOAD_MIN_CHARS:-2}"
|
|
3734
|
-
local target_manager=""
|
|
3735
|
-
local should_warm_bun=0
|
|
3736
|
-
|
|
3737
|
-
if ! [[ "${min_chars}" =~ ^[0-9]+$ ]]; then
|
|
3738
|
-
min_chars=2
|
|
3739
|
-
fi
|
|
3740
|
-
|
|
3741
|
-
if [[ ${#query} -lt ${min_chars} ]]; then
|
|
3742
|
-
run_ipc_reload_action "${query}" || send_fzf_prompt_action "Search> " || true
|
|
3743
|
-
return 0
|
|
3744
|
-
fi
|
|
3745
|
-
|
|
3746
|
-
if [[ -z "${fallback_file}" || ! -r "${fallback_file}" ]]; then
|
|
3747
|
-
return 1
|
|
3748
|
-
fi
|
|
3749
|
-
|
|
3750
|
-
if [[ -n "${manager_override}" ]]; then
|
|
3751
|
-
manager_override="$(normalize_manager "${manager_override}")"
|
|
3752
|
-
manager_supported "${manager_override}" || return 1
|
|
3753
|
-
target_manager="${manager_override}"
|
|
3754
|
-
else
|
|
3755
|
-
target_manager="bun"
|
|
3756
|
-
fi
|
|
3757
|
-
|
|
3758
|
-
if [[ "${target_manager}" == "bun" ]] && manager_command_ready bun && [[ -n "${FZF_PORT:-}" ]]; then
|
|
3759
|
-
should_warm_bun=1
|
|
3760
|
-
fi
|
|
3761
|
-
|
|
3762
|
-
send_fzf_prompt_action "Loading> " || true
|
|
3763
|
-
|
|
3764
|
-
if [[ "${should_warm_bun}" -eq 1 ]]; then
|
|
3765
|
-
(
|
|
3766
|
-
FPF_IPC_MANAGER_OVERRIDE="${manager_override}" \
|
|
3767
|
-
FPF_IPC_FALLBACK_FILE="${fallback_file}" \
|
|
3768
|
-
manager_search_entries "bun" "${query}" >/dev/null 2>&1 || true
|
|
3769
|
-
) &
|
|
3770
|
-
fi
|
|
3771
|
-
|
|
3772
|
-
run_ipc_reload_action "${query}" || send_fzf_prompt_action "Search> " || true
|
|
3773
|
-
}
|
|
3774
|
-
|
|
3775
|
-
manager_dispatch_action() {
|
|
3776
|
-
local manager="$1"
|
|
3777
|
-
local action="$2"
|
|
3778
|
-
shift 2 || true
|
|
3779
|
-
manager_execute_action "${manager}" "${action}" "$@"
|
|
3780
|
-
}
|
|
3781
|
-
|
|
3782
|
-
manager_install() {
|
|
3783
|
-
local manager="$1"
|
|
3784
|
-
shift
|
|
3785
|
-
manager_dispatch_action "${manager}" "install" "$@"
|
|
3786
|
-
}
|
|
3787
|
-
|
|
3788
|
-
manager_remove() {
|
|
3789
|
-
local manager="$1"
|
|
3790
|
-
shift
|
|
3791
|
-
manager_execute_action "${manager}" "remove" "$@"
|
|
3792
|
-
}
|
|
3793
|
-
|
|
3794
|
-
manager_show_info() {
|
|
3795
|
-
local manager="$1"
|
|
3796
|
-
local package="$2"
|
|
3797
|
-
manager_execute_action "${manager}" "show_info" "${package}"
|
|
3798
|
-
}
|
|
3799
|
-
|
|
3800
|
-
manager_update() {
|
|
3801
|
-
local manager="$1"
|
|
3802
|
-
manager_execute_action "${manager}" "update"
|
|
3803
|
-
}
|
|
3804
|
-
|
|
3805
|
-
manager_refresh() {
|
|
3806
|
-
local manager="$1"
|
|
3807
|
-
manager_execute_action "${manager}" "refresh"
|
|
3808
|
-
}
|
|
3809
|
-
|
|
3810
|
-
confirm_action() {
|
|
3811
|
-
local prompt="$1"
|
|
3812
|
-
local reply=""
|
|
3813
|
-
local normalized_reply=""
|
|
3814
|
-
|
|
3815
|
-
if assume_yes_enabled; then
|
|
3816
|
-
return 0
|
|
3817
|
-
fi
|
|
3818
|
-
|
|
3819
|
-
printf "%s [y/N]: " "${prompt}" >&2
|
|
3820
|
-
read -r reply || true
|
|
3821
|
-
reply="$(trim_whitespace "${reply}")"
|
|
3822
|
-
normalized_reply="${reply,,}"
|
|
3823
|
-
|
|
3824
|
-
case "${normalized_reply}" in
|
|
3825
|
-
y|yes)
|
|
3826
|
-
return 0
|
|
3827
|
-
;;
|
|
3828
|
-
*)
|
|
3829
|
-
return 1
|
|
3830
|
-
;;
|
|
3831
|
-
esac
|
|
3832
|
-
}
|
|
3833
|
-
|
|
3834
|
-
run_fuzzy_selector() {
|
|
3835
|
-
local query="$1"
|
|
3836
|
-
local input_file="$2"
|
|
3837
|
-
local header_line="$3"
|
|
3838
|
-
local reload_cmd="${4:-}"
|
|
3839
|
-
local reload_ipc_cmd="${5:-}"
|
|
3840
|
-
local script_path="$(invocation_script_path)"
|
|
3841
|
-
local quoted_script_path=""
|
|
3842
|
-
local quoted_help_file=""
|
|
3843
|
-
local quoted_kbinds_file=""
|
|
3844
|
-
local preview_cmd
|
|
3845
|
-
local fzf_shell
|
|
3846
|
-
|
|
3847
|
-
printf -v quoted_script_path "%q" "${script_path}"
|
|
3848
|
-
printf -v quoted_help_file "%q" "${HELP_FILE}"
|
|
3849
|
-
printf -v quoted_kbinds_file "%q" "${KBINDS_FILE}"
|
|
3850
|
-
|
|
3851
|
-
preview_cmd="FPF_SESSION_TMP_ROOT=$(printf '%q' "${SESSION_TMP_ROOT}") ${quoted_script_path} --preview-item --manager {1} -- {2}"
|
|
3852
|
-
if command_exists bash; then
|
|
3853
|
-
fzf_shell="bash"
|
|
3854
|
-
else
|
|
3855
|
-
fzf_shell=""
|
|
3856
|
-
fi
|
|
3857
|
-
|
|
3858
|
-
local -a fzf_args=()
|
|
3859
|
-
fzf_args=(-q "${query}" -m \
|
|
3860
|
-
-e \
|
|
3861
|
-
--delimiter=$'\t' \
|
|
3862
|
-
--with-nth=1,2,3 \
|
|
3863
|
-
--preview="${preview_cmd}" \
|
|
3864
|
-
--preview-window=55%:wrap:border-sharp \
|
|
3865
|
-
--layout=reverse \
|
|
3866
|
-
--marker='>>' \
|
|
3867
|
-
--prompt='Search> ' \
|
|
3868
|
-
--header="${header_line}" \
|
|
3869
|
-
--info=inline \
|
|
3870
|
-
--margin="2%,1%,2%,1%" \
|
|
3871
|
-
--cycle \
|
|
3872
|
-
--tiebreak=begin,chunk,length \
|
|
3873
|
-
--bind="ctrl-k:preview:cat ${quoted_kbinds_file}" \
|
|
3874
|
-
--bind="ctrl-h:preview:cat ${quoted_help_file}" \
|
|
3875
|
-
--bind='ctrl-/:change-preview-window(hidden|)' \
|
|
3876
|
-
--bind=ctrl-n:next-selected,ctrl-b:prev-selected \
|
|
3877
|
-
--bind='focus:transform-preview-label:echo [{1}] {2}')
|
|
3878
|
-
|
|
3879
|
-
if [[ -n "${reload_ipc_cmd}" ]]; then
|
|
3880
|
-
fzf_args+=(--listen=0)
|
|
3881
|
-
fzf_args+=(--bind="change:execute-silent:${reload_ipc_cmd}")
|
|
3882
|
-
if [[ -n "${reload_cmd}" ]]; then
|
|
3883
|
-
if fzf_supports_result_bind; then
|
|
3884
|
-
fzf_args+=(--bind="ctrl-r:change-prompt(Loading> )+reload:${reload_cmd}")
|
|
3885
|
-
fzf_args+=(--bind="result:change-prompt(Search> )")
|
|
3886
|
-
else
|
|
3887
|
-
fzf_args+=(--bind="ctrl-r:reload:${reload_cmd}")
|
|
3888
|
-
fi
|
|
3889
|
-
fi
|
|
3890
|
-
elif [[ -n "${reload_cmd}" ]]; then
|
|
3891
|
-
if fzf_supports_result_bind; then
|
|
3892
|
-
fzf_args+=(--bind="change:change-prompt(Loading> )+reload:${reload_cmd}")
|
|
3893
|
-
fzf_args+=(--bind="ctrl-r:change-prompt(Loading> )+reload:${reload_cmd}")
|
|
3894
|
-
fzf_args+=(--bind="result:change-prompt(Search> )")
|
|
3895
|
-
else
|
|
3896
|
-
fzf_args+=(--bind="change:reload:${reload_cmd}")
|
|
3897
|
-
fzf_args+=(--bind="ctrl-r:reload:${reload_cmd}")
|
|
3898
|
-
fi
|
|
3899
|
-
fi
|
|
3900
|
-
|
|
3901
|
-
if [[ -n "${fzf_shell}" ]]; then
|
|
3902
|
-
SHELL="${fzf_shell}" fzf "${fzf_args[@]}" <"${input_file}"
|
|
3903
|
-
else
|
|
3904
|
-
fzf "${fzf_args[@]}" <"${input_file}"
|
|
3905
|
-
fi
|
|
3906
|
-
}
|
|
3907
|
-
|
|
3908
|
-
main() {
|
|
3909
|
-
ensure_tmp_root
|
|
3910
|
-
initialize_session_tmp_root
|
|
3911
|
-
load_fpf_libraries
|
|
3912
|
-
if [[ -z "${FPF_SESSION_TMP_ROOT:-}" ]]; then
|
|
3913
|
-
trap cleanup_session_tmp_root EXIT
|
|
3914
|
-
fi
|
|
3915
|
-
|
|
3916
|
-
parse_args "$@"
|
|
3917
|
-
|
|
3918
|
-
if [[ "${ACTION}" == "ipc-reload" ]]; then
|
|
3919
|
-
run_ipc_reload_action "$(join_query)" || true
|
|
3920
|
-
exit 0
|
|
3921
|
-
fi
|
|
3922
|
-
|
|
3923
|
-
if [[ "${ACTION}" == "ipc-query-notify" ]]; then
|
|
3924
|
-
run_ipc_query_notify_action "$(join_query)" || true
|
|
3925
|
-
exit 0
|
|
3926
|
-
fi
|
|
3927
|
-
|
|
3928
|
-
if [[ "${ACTION}" == "dynamic-reload" ]]; then
|
|
3929
|
-
run_dynamic_reload_action "$(join_query)" || true
|
|
3930
|
-
exit 0
|
|
3931
|
-
fi
|
|
3932
|
-
|
|
3933
|
-
if [[ "${ACTION}" == "preview-item" ]]; then
|
|
3934
|
-
local preview_manager="${MANAGER_OVERRIDE:-}"
|
|
3935
|
-
local preview_package
|
|
3936
|
-
|
|
3937
|
-
preview_package="$(join_query)"
|
|
3938
|
-
run_preview_item_action "${preview_manager}" "${preview_package}" || true
|
|
3939
|
-
exit 0
|
|
3940
|
-
fi
|
|
3941
|
-
|
|
3942
|
-
if [[ "${ACTION}" == "bun-refresh-worker" ]]; then
|
|
3943
|
-
local worker_manager="${MANAGER_OVERRIDE:-bun}"
|
|
3944
|
-
local worker_query
|
|
3945
|
-
local worker_flags
|
|
3946
|
-
local worker_key
|
|
3947
|
-
local worker_fingerprint
|
|
3948
|
-
local worker_generation
|
|
3949
|
-
|
|
3950
|
-
worker_query="$(join_query)"
|
|
3951
|
-
worker_flags="${FPF_BUN_REFRESH_FLAGS:-$(query_cache_flags)}"
|
|
3952
|
-
worker_key="${FPF_BUN_REFRESH_KEY:-$(cache_query_key "${worker_manager}" "${worker_query}" "${worker_flags}")}"
|
|
3953
|
-
worker_fingerprint="${FPF_BUN_REFRESH_FINGERPRINT:-$(cache_fingerprint "${worker_manager}" "${worker_query}" "${worker_flags}")}"
|
|
3954
|
-
worker_generation="${FPF_BUN_REFRESH_GENERATION:-0}"
|
|
3955
|
-
|
|
3956
|
-
if ! [[ "${worker_generation}" =~ ^[0-9]+$ ]] || [[ "${worker_generation}" -le 0 ]]; then
|
|
3957
|
-
exit 0
|
|
3958
|
-
fi
|
|
3959
|
-
|
|
3960
|
-
initialize_cache_root
|
|
3961
|
-
bun_run_refresh_worker "${worker_manager}" "${worker_query}" "${worker_flags}" "${worker_key}" "${worker_fingerprint}" "${worker_generation}" || true
|
|
3962
|
-
exit 0
|
|
3963
|
-
fi
|
|
3964
|
-
|
|
3965
|
-
if [[ "${ACTION}" == "version" ]]; then
|
|
3966
|
-
print_version
|
|
3967
|
-
exit 0
|
|
3968
|
-
fi
|
|
3969
|
-
|
|
3970
|
-
local detected_manager
|
|
3971
|
-
local detected_managers=()
|
|
3972
|
-
while IFS= read -r detected_manager; do
|
|
3973
|
-
[[ -n "${detected_manager}" ]] || continue
|
|
3974
|
-
detected_managers+=("${detected_manager}")
|
|
3975
|
-
done < <(detect_default_managers)
|
|
3976
|
-
|
|
3977
|
-
local default_managers_display
|
|
3978
|
-
default_managers_display="$(join_manager_labels_with_ids "${detected_managers[@]-}")"
|
|
3979
|
-
[[ -n "${default_managers_display}" ]] || default_managers_display="None"
|
|
3980
|
-
|
|
3981
|
-
build_help_file "${default_managers_display}"
|
|
3982
|
-
build_keybind_file
|
|
3983
|
-
|
|
3984
|
-
if [[ "${ACTION}" == "help" ]]; then
|
|
3985
|
-
print_help
|
|
3986
|
-
exit 0
|
|
3987
|
-
fi
|
|
3988
|
-
|
|
3989
|
-
local managers=()
|
|
3990
|
-
local manager_list_override="${FPF_MANAGER_LIST_OVERRIDE:-}"
|
|
3991
|
-
local manager_list_entry=""
|
|
3992
|
-
local normalized_manager=""
|
|
3993
|
-
local manager_seen=""
|
|
3994
|
-
local -a manager_list_entries=()
|
|
3995
|
-
if [[ -n "${MANAGER_OVERRIDE}" ]]; then
|
|
3996
|
-
managers+=("$(normalize_manager "${MANAGER_OVERRIDE}")")
|
|
3997
|
-
elif [[ -n "${manager_list_override}" ]]; then
|
|
3998
|
-
IFS=',' read -r -a manager_list_entries <<<"${manager_list_override}"
|
|
3999
|
-
for manager_list_entry in "${manager_list_entries[@]-}"; do
|
|
4000
|
-
manager_list_entry="$(trim_whitespace "${manager_list_entry}")"
|
|
4001
|
-
[[ -n "${manager_list_entry}" ]] || continue
|
|
4002
|
-
|
|
4003
|
-
normalized_manager="$(normalize_manager "${manager_list_entry}")"
|
|
4004
|
-
if ! manager_supported "${normalized_manager}" || ! manager_command_ready "${normalized_manager}"; then
|
|
4005
|
-
continue
|
|
4006
|
-
fi
|
|
4007
|
-
|
|
4008
|
-
case " ${manager_seen} " in
|
|
4009
|
-
*" ${normalized_manager} "*)
|
|
4010
|
-
continue
|
|
4011
|
-
;;
|
|
4012
|
-
esac
|
|
4013
|
-
manager_seen+=" ${normalized_manager}"
|
|
4014
|
-
managers+=("${normalized_manager}")
|
|
4015
|
-
done
|
|
4016
|
-
else
|
|
4017
|
-
for detected_manager in "${detected_managers[@]-}"; do
|
|
4018
|
-
[[ -n "${detected_manager}" ]] || continue
|
|
4019
|
-
managers+=("${detected_manager}")
|
|
4020
|
-
done
|
|
4021
|
-
fi
|
|
4022
|
-
|
|
4023
|
-
if [[ "${#managers[@]}" -eq 0 ]]; then
|
|
4024
|
-
die "Unable to auto-detect supported package managers. Use --manager."
|
|
4025
|
-
fi
|
|
4026
|
-
|
|
4027
|
-
local manager
|
|
4028
|
-
for manager in "${managers[@]-}"; do
|
|
4029
|
-
manager_supported "${manager}" || die "Unsupported manager: ${manager}"
|
|
4030
|
-
manager_command_ready "${manager}" || die "Manager command(s) for '${manager}' not found on this system"
|
|
4031
|
-
done
|
|
4032
|
-
|
|
4033
|
-
local manager_display
|
|
4034
|
-
manager_display="$(join_manager_labels "${managers[@]-}")"
|
|
4035
|
-
|
|
4036
|
-
local query
|
|
4037
|
-
query="$(join_query)"
|
|
4038
|
-
|
|
4039
|
-
if [[ "${ACTION}" != "feed-search" ]]; then
|
|
4040
|
-
log "Using manager(s): ${manager_display}"
|
|
4041
|
-
fi
|
|
4042
|
-
|
|
4043
|
-
if [[ "${ACTION}" == "update" ]]; then
|
|
4044
|
-
if confirm_action "Run update/upgrade for ${manager_display}?"; then
|
|
4045
|
-
for manager in "${managers[@]-}"; do
|
|
4046
|
-
log "Updating with $(manager_label "${manager}")"
|
|
4047
|
-
manager_update "${manager}"
|
|
4048
|
-
done
|
|
4049
|
-
else
|
|
4050
|
-
log "Update canceled"
|
|
4051
|
-
fi
|
|
4052
|
-
exit 0
|
|
4053
|
-
fi
|
|
4054
|
-
|
|
4055
|
-
if [[ "${ACTION}" == "refresh" ]]; then
|
|
4056
|
-
if confirm_action "Refresh package catalogs for ${manager_display}?"; then
|
|
4057
|
-
for manager in "${managers[@]-}"; do
|
|
4058
|
-
log "Refreshing catalogs with $(manager_label "${manager}")"
|
|
4059
|
-
manager_refresh "${manager}"
|
|
4060
|
-
done
|
|
4061
|
-
else
|
|
4062
|
-
log "Refresh canceled"
|
|
4063
|
-
fi
|
|
4064
|
-
exit 0
|
|
4065
|
-
fi
|
|
4066
|
-
|
|
4067
|
-
local display_file
|
|
4068
|
-
display_file="$(mktemp "${SESSION_TMP_ROOT}/display.XXXXXX")"
|
|
4069
|
-
: >"${display_file}"
|
|
4070
|
-
|
|
4071
|
-
if [[ "${ACTION}" == "feed-search" ]]; then
|
|
4072
|
-
collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"
|
|
4073
|
-
if [[ -s "${display_file}" ]]; then
|
|
4074
|
-
cat "${display_file}"
|
|
4075
|
-
fi
|
|
4076
|
-
rm -f "${display_file}"
|
|
4077
|
-
exit 0
|
|
4078
|
-
fi
|
|
4079
|
-
|
|
4080
|
-
ensure_fzf "${managers[@]-}"
|
|
4081
|
-
|
|
4082
|
-
if [[ "${ACTION}" == "search" ]]; then
|
|
4083
|
-
loading_progress_begin "${managers[@]-}"
|
|
4084
|
-
if ! run_with_loading_indicator "Loading packages from ${manager_display}" collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"; then
|
|
4085
|
-
loading_progress_end
|
|
4086
|
-
die "Failed to load package search results."
|
|
4087
|
-
fi
|
|
4088
|
-
loading_progress_end
|
|
4089
|
-
else
|
|
4090
|
-
loading_progress_begin "${managers[@]-}"
|
|
4091
|
-
if ! run_with_loading_indicator "Loading installed packages from ${manager_display}" collect_installed_display_rows "${display_file}" "${managers[@]-}"; then
|
|
4092
|
-
loading_progress_end
|
|
4093
|
-
die "Failed to load installed package results."
|
|
4094
|
-
fi
|
|
4095
|
-
loading_progress_end
|
|
4096
|
-
fi
|
|
4097
|
-
|
|
4098
|
-
if [[ ! -s "${display_file}" ]]; then
|
|
4099
|
-
rm -f "${display_file}"
|
|
4100
|
-
|
|
4101
|
-
if [[ "${ACTION}" == "search" && -z "${query}" && "${#managers[@]}" -eq 1 ]]; then
|
|
4102
|
-
local setup_message=""
|
|
4103
|
-
setup_message="$(manager_no_query_setup_message "${managers[0]}" || true)"
|
|
4104
|
-
if [[ -n "${setup_message}" ]]; then
|
|
4105
|
-
die "${setup_message}"
|
|
4106
|
-
fi
|
|
4107
|
-
fi
|
|
4108
|
-
|
|
4109
|
-
if [[ -n "${query}" ]]; then
|
|
4110
|
-
die "No packages found for ${manager_display} matching '${query}'. Try a broader query or --manager."
|
|
4111
|
-
fi
|
|
4112
|
-
die "No packages found for ${manager_display}. Try adding a query or using --manager."
|
|
4113
|
-
fi
|
|
4114
|
-
|
|
4115
|
-
local header
|
|
4116
|
-
case "${ACTION}" in
|
|
4117
|
-
search)
|
|
4118
|
-
header="Select package(s) to install with ${manager_display} (TAB to multi-select, * = installed)"
|
|
4119
|
-
;;
|
|
4120
|
-
list)
|
|
4121
|
-
header="Select installed package(s) to inspect from ${manager_display}"
|
|
4122
|
-
;;
|
|
4123
|
-
remove)
|
|
4124
|
-
header="Select installed package(s) to remove from ${manager_display}"
|
|
4125
|
-
;;
|
|
4126
|
-
*)
|
|
4127
|
-
header="Select package(s)"
|
|
4128
|
-
;;
|
|
4129
|
-
esac
|
|
4130
|
-
|
|
4131
|
-
local reload_cmd=""
|
|
4132
|
-
local reload_ipc_cmd=""
|
|
4133
|
-
local reload_fallback_file="${display_file}"
|
|
4134
|
-
local reload_manager_list=""
|
|
4135
|
-
if [[ "${ACTION}" == "search" ]]; then
|
|
4136
|
-
if dynamic_reload_enabled "${#managers[@]}"; then
|
|
4137
|
-
reload_manager_list="$(IFS=,; printf "%s" "${managers[*]-}")"
|
|
4138
|
-
|
|
4139
|
-
if [[ -n "${query}" ]]; then
|
|
4140
|
-
reload_fallback_file="$(mktemp "${SESSION_TMP_ROOT}/reload-fallback.XXXXXX")"
|
|
4141
|
-
loading_progress_begin "${managers[@]-}"
|
|
4142
|
-
if ! run_with_loading_indicator "Preparing baseline search results" collect_search_display_rows "" "${reload_fallback_file}" "${managers[@]-}"; then
|
|
4143
|
-
loading_progress_end
|
|
4144
|
-
die "Failed to prepare baseline search results."
|
|
4145
|
-
fi
|
|
4146
|
-
loading_progress_end
|
|
4147
|
-
if [[ ! -s "${reload_fallback_file}" ]]; then
|
|
4148
|
-
cp "${display_file}" "${reload_fallback_file}"
|
|
4149
|
-
fi
|
|
4150
|
-
fi
|
|
4151
|
-
|
|
4152
|
-
reload_cmd="$(build_dynamic_reload_command "${MANAGER_OVERRIDE}" "${reload_fallback_file}" "${reload_manager_list}")"
|
|
4153
|
-
if dynamic_reload_use_ipc; then
|
|
4154
|
-
reload_ipc_cmd="$(build_dynamic_query_notify_ipc_command "${MANAGER_OVERRIDE}" "${reload_fallback_file}" "${reload_manager_list}")"
|
|
4155
|
-
fi
|
|
4156
|
-
fi
|
|
4157
|
-
fi
|
|
4158
|
-
|
|
4159
|
-
local selected
|
|
4160
|
-
selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" "${reload_cmd}" "${reload_ipc_cmd}" || true)"
|
|
4161
|
-
|
|
4162
|
-
rm -f "${display_file}"
|
|
4163
|
-
if [[ "${reload_fallback_file}" != "${display_file}" ]]; then
|
|
4164
|
-
rm -f "${reload_fallback_file}"
|
|
4165
|
-
fi
|
|
4166
|
-
|
|
4167
|
-
if [[ -z "${selected}" ]]; then
|
|
4168
|
-
log "Selection canceled"
|
|
4169
|
-
exit 0
|
|
4170
|
-
fi
|
|
4171
|
-
|
|
4172
|
-
local selected_managers=()
|
|
4173
|
-
local selected_packages=()
|
|
4174
|
-
local selected_line
|
|
4175
|
-
local selected_line_number=0
|
|
4176
|
-
local selected_parse_failures=0
|
|
4177
|
-
local selected_manager
|
|
4178
|
-
local selected_pkg
|
|
4179
|
-
local normalized_selected_manager
|
|
4180
|
-
while IFS= read -r selected_line; do
|
|
4181
|
-
selected_line_number=$((selected_line_number + 1))
|
|
4182
|
-
[[ -n "${selected_line}" ]] || continue
|
|
4183
|
-
IFS=$'\t' read -r selected_manager selected_pkg _ <<<"${selected_line}"
|
|
4184
|
-
selected_manager="$(trim_whitespace "${selected_manager}")"
|
|
4185
|
-
selected_pkg="$(trim_whitespace "${selected_pkg}")"
|
|
4186
|
-
|
|
4187
|
-
if [[ -z "${selected_manager}" || -z "${selected_pkg}" ]]; then
|
|
4188
|
-
selected_parse_failures=$((selected_parse_failures + 1))
|
|
4189
|
-
log_selection_parse_skip "${selected_line_number}" "missing manager/package fields" "${selected_line}"
|
|
4190
|
-
continue
|
|
4191
|
-
fi
|
|
4192
|
-
|
|
4193
|
-
normalized_selected_manager="$(normalize_manager "${selected_manager}")"
|
|
4194
|
-
if ! manager_supported "${normalized_selected_manager}"; then
|
|
4195
|
-
selected_parse_failures=$((selected_parse_failures + 1))
|
|
4196
|
-
log_selection_parse_skip "${selected_line_number}" "unsupported manager '${normalized_selected_manager}'" "${selected_line}"
|
|
4197
|
-
continue
|
|
4198
|
-
fi
|
|
4199
|
-
|
|
4200
|
-
selected_managers+=("${normalized_selected_manager}")
|
|
4201
|
-
selected_packages+=("${selected_pkg}")
|
|
4202
|
-
done <<<"${selected}"
|
|
4203
|
-
|
|
4204
|
-
if [[ "${#selected_packages[@]}" -eq 0 ]]; then
|
|
4205
|
-
if [[ "${selected_parse_failures}" -gt 0 ]] && selection_debug_enabled; then
|
|
4206
|
-
log "Debug(selection): no executable entries after parsing ${selected_parse_failures} selected line(s)"
|
|
4207
|
-
fi
|
|
4208
|
-
log "Selection canceled"
|
|
4209
|
-
exit 0
|
|
4210
|
-
fi
|
|
4211
|
-
|
|
4212
|
-
local unique_managers=()
|
|
4213
|
-
local candidate_manager
|
|
4214
|
-
local already_seen
|
|
4215
|
-
local existing_manager
|
|
4216
|
-
for candidate_manager in "${selected_managers[@]-}"; do
|
|
4217
|
-
already_seen=0
|
|
4218
|
-
for existing_manager in "${unique_managers[@]-}"; do
|
|
4219
|
-
if [[ "${existing_manager}" == "${candidate_manager}" ]]; then
|
|
4220
|
-
already_seen=1
|
|
4221
|
-
break
|
|
4222
|
-
fi
|
|
4223
|
-
done
|
|
4224
|
-
if [[ "${already_seen}" -eq 0 ]]; then
|
|
4225
|
-
unique_managers+=("${candidate_manager}")
|
|
4226
|
-
fi
|
|
4227
|
-
done
|
|
4228
|
-
|
|
4229
|
-
local selected_manager_display
|
|
4230
|
-
selected_manager_display="$(join_manager_labels "${unique_managers[@]-}")"
|
|
4231
|
-
|
|
4232
|
-
local idx
|
|
4233
|
-
local mgr_packages=()
|
|
4234
|
-
|
|
4235
|
-
case "${ACTION}" in
|
|
4236
|
-
search)
|
|
4237
|
-
if confirm_action "Install ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
4238
|
-
for manager in "${unique_managers[@]-}"; do
|
|
4239
|
-
mgr_packages=()
|
|
4240
|
-
for idx in "${!selected_packages[@]}"; do
|
|
4241
|
-
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
4242
|
-
mgr_packages+=("${selected_packages[$idx]}")
|
|
4243
|
-
fi
|
|
4244
|
-
done
|
|
4245
|
-
if [[ "${#mgr_packages[@]}" -gt 0 ]]; then
|
|
4246
|
-
log "Installing ${#mgr_packages[@]} package(s) with $(manager_label "${manager}")"
|
|
4247
|
-
manager_install "${manager}" "${mgr_packages[@]-}"
|
|
4248
|
-
fi
|
|
4249
|
-
done
|
|
4250
|
-
else
|
|
4251
|
-
log "Install canceled"
|
|
4252
|
-
fi
|
|
4253
|
-
;;
|
|
4254
|
-
remove)
|
|
4255
|
-
if confirm_action "Remove ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
4256
|
-
for manager in "${unique_managers[@]-}"; do
|
|
4257
|
-
mgr_packages=()
|
|
4258
|
-
for idx in "${!selected_packages[@]}"; do
|
|
4259
|
-
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
4260
|
-
mgr_packages+=("${selected_packages[$idx]}")
|
|
4261
|
-
fi
|
|
4262
|
-
done
|
|
4263
|
-
if [[ "${#mgr_packages[@]}" -gt 0 ]]; then
|
|
4264
|
-
log "Removing ${#mgr_packages[@]} package(s) with $(manager_label "${manager}")"
|
|
4265
|
-
manager_remove "${manager}" "${mgr_packages[@]-}"
|
|
4266
|
-
fi
|
|
4267
|
-
done
|
|
4268
|
-
else
|
|
4269
|
-
log "Remove canceled"
|
|
4270
|
-
fi
|
|
4271
|
-
;;
|
|
4272
|
-
list)
|
|
4273
|
-
for idx in "${!selected_packages[@]}"; do
|
|
4274
|
-
printf "\n=== %s (%s) ===\n" "${selected_packages[$idx]}" "$(manager_label "${selected_managers[$idx]}")"
|
|
4275
|
-
manager_show_info "${selected_managers[$idx]}" "${selected_packages[$idx]}" || true
|
|
4276
|
-
done
|
|
4277
|
-
;;
|
|
4278
|
-
esac
|
|
4279
127
|
}
|
|
4280
128
|
|
|
4281
129
|
main "$@"
|