fpf-cli 1.6.14 → 1.6.16
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 +1 -0
- package/fpf +1207 -73
- package/package.json +1 -1
package/fpf
CHANGED
|
@@ -3,16 +3,24 @@
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
5
|
SCRIPT_NAME="fpf"
|
|
6
|
-
SCRIPT_VERSION="1.6.
|
|
6
|
+
SCRIPT_VERSION="1.6.16"
|
|
7
7
|
TMP_ROOT="${TMPDIR:-/tmp}/fpf"
|
|
8
8
|
SESSION_TMP_ROOT=""
|
|
9
9
|
HELP_FILE=""
|
|
10
10
|
KBINDS_FILE=""
|
|
11
|
+
CACHE_FORMAT_VERSION="1"
|
|
12
|
+
CACHE_ROOT=""
|
|
11
13
|
|
|
12
14
|
ACTION="search"
|
|
13
15
|
MANAGER_OVERRIDE=""
|
|
16
|
+
IPC_MANAGER_OVERRIDE=""
|
|
17
|
+
IPC_FALLBACK_FILE=""
|
|
14
18
|
declare -a QUERY_PARTS=()
|
|
15
19
|
|
|
20
|
+
query_cache_flags() {
|
|
21
|
+
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}"
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
log() {
|
|
17
25
|
printf "%s\n" "$*" >&2
|
|
18
26
|
}
|
|
@@ -30,16 +38,672 @@ ensure_tmp_root() {
|
|
|
30
38
|
mkdir -p "${TMP_ROOT}"
|
|
31
39
|
}
|
|
32
40
|
|
|
41
|
+
resolve_cache_root() {
|
|
42
|
+
local os
|
|
43
|
+
os="$(uname -s)"
|
|
44
|
+
|
|
45
|
+
if [[ -n "${FPF_CACHE_DIR:-}" ]]; then
|
|
46
|
+
printf "%s" "${FPF_CACHE_DIR}"
|
|
47
|
+
return
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
case "${os}" in
|
|
51
|
+
Darwin)
|
|
52
|
+
printf "%s" "${HOME}/Library/Caches/fpf"
|
|
53
|
+
;;
|
|
54
|
+
Linux)
|
|
55
|
+
if [[ -n "${XDG_CACHE_HOME:-}" ]]; then
|
|
56
|
+
printf "%s" "${XDG_CACHE_HOME}/fpf"
|
|
57
|
+
else
|
|
58
|
+
printf "%s" "${HOME}/.cache/fpf"
|
|
59
|
+
fi
|
|
60
|
+
;;
|
|
61
|
+
MINGW*|MSYS*|CYGWIN*|Windows_NT)
|
|
62
|
+
if [[ -n "${LOCALAPPDATA:-}" ]]; then
|
|
63
|
+
printf "%s" "${LOCALAPPDATA}/fpf"
|
|
64
|
+
elif [[ -n "${APPDATA:-}" ]]; then
|
|
65
|
+
printf "%s" "${APPDATA}/fpf"
|
|
66
|
+
else
|
|
67
|
+
printf "%s" "${HOME}/.cache/fpf"
|
|
68
|
+
fi
|
|
69
|
+
;;
|
|
70
|
+
*)
|
|
71
|
+
printf "%s" "${HOME}/.cache/fpf"
|
|
72
|
+
;;
|
|
73
|
+
esac
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
initialize_cache_root() {
|
|
77
|
+
if [[ -n "${CACHE_ROOT}" ]]; then
|
|
78
|
+
return
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
CACHE_ROOT="$(resolve_cache_root)"
|
|
82
|
+
mkdir -p "${CACHE_ROOT}"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
normalize_cache_query() {
|
|
86
|
+
printf "%s" "$1" |
|
|
87
|
+
awk '{
|
|
88
|
+
line=$0
|
|
89
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
|
|
90
|
+
gsub(/[[:space:]]+/, " ", line)
|
|
91
|
+
print tolower(line)
|
|
92
|
+
}'
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
platform_cache_token() {
|
|
96
|
+
uname -s | tr '[:upper:]' '[:lower:]'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
cache_fingerprint() {
|
|
100
|
+
local manager="$1"
|
|
101
|
+
local query="$2"
|
|
102
|
+
local flags="$3"
|
|
103
|
+
local normalized_query
|
|
104
|
+
|
|
105
|
+
normalized_query="$(normalize_cache_query "${query}")"
|
|
106
|
+
printf "%s|%s|%s|%s|%s" "${CACHE_FORMAT_VERSION}" "${manager}" "$(platform_cache_token)" "${normalized_query}" "${flags}"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
cache_cksum() {
|
|
110
|
+
local input="$1"
|
|
111
|
+
printf "%s" "${input}" | cksum | awk '{ print $1 }'
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
cache_catalog_key() {
|
|
115
|
+
local manager="$1"
|
|
116
|
+
printf "catalog/%s.tsv" "${manager}"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
cache_search_catalog_fingerprint() {
|
|
120
|
+
local manager="$1"
|
|
121
|
+
local command_path=""
|
|
122
|
+
local extra_token=""
|
|
123
|
+
|
|
124
|
+
case "${manager}" in
|
|
125
|
+
apt)
|
|
126
|
+
command_path="$(command -v apt-cache 2>/dev/null || printf "missing")"
|
|
127
|
+
if [[ "${FPF_TEST_FIXTURES:-0}" == "1" ]]; then
|
|
128
|
+
extra_token="|fixtures=${FPF_TEST_FIXTURE_DIR:-enabled}"
|
|
129
|
+
fi
|
|
130
|
+
;;
|
|
131
|
+
brew)
|
|
132
|
+
command_path="$(command -v brew 2>/dev/null || printf "missing")"
|
|
133
|
+
if [[ "${FPF_TEST_FIXTURES:-0}" == "1" ]]; then
|
|
134
|
+
extra_token="|fixtures=${FPF_TEST_FIXTURE_DIR:-enabled}"
|
|
135
|
+
fi
|
|
136
|
+
;;
|
|
137
|
+
*)
|
|
138
|
+
command_path="n/a"
|
|
139
|
+
;;
|
|
140
|
+
esac
|
|
141
|
+
|
|
142
|
+
printf "%s|cmd=%s%s" "$(cache_fingerprint "${manager}" "" "search-catalog")" "${command_path}" "${extra_token}"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
cache_search_catalog_key() {
|
|
146
|
+
local manager="$1"
|
|
147
|
+
local fingerprint="$2"
|
|
148
|
+
local checksum
|
|
149
|
+
|
|
150
|
+
checksum="$(cache_cksum "${fingerprint}")"
|
|
151
|
+
printf "search-catalog/%s/%s.tsv" "${manager}" "${checksum}"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
cache_query_key() {
|
|
155
|
+
local manager="$1"
|
|
156
|
+
local query="$2"
|
|
157
|
+
local flags="$3"
|
|
158
|
+
local fingerprint
|
|
159
|
+
local checksum
|
|
160
|
+
|
|
161
|
+
fingerprint="$(cache_fingerprint "${manager}" "${query}" "${flags}")"
|
|
162
|
+
checksum="$(cache_cksum "${fingerprint}")"
|
|
163
|
+
printf "query/%s/%s.tsv" "${manager}" "${checksum}"
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
cache_meta_key() {
|
|
167
|
+
local key="$1"
|
|
168
|
+
printf "meta/%s.meta" "${key}"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
cache_path_for_key() {
|
|
172
|
+
local key="$1"
|
|
173
|
+
printf "%s/%s" "${CACHE_ROOT}" "${key}"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
cache_atomic_write_from_file() {
|
|
177
|
+
local source_file="$1"
|
|
178
|
+
local destination_file="$2"
|
|
179
|
+
local destination_dir
|
|
180
|
+
local destination_base
|
|
181
|
+
local temp_file
|
|
182
|
+
|
|
183
|
+
destination_dir="$(dirname "${destination_file}")"
|
|
184
|
+
destination_base="$(basename "${destination_file}")"
|
|
185
|
+
|
|
186
|
+
mkdir -p "${destination_dir}"
|
|
187
|
+
temp_file="$(mktemp "${destination_dir}/.${destination_base}.tmp.XXXXXX")"
|
|
188
|
+
cp "${source_file}" "${temp_file}"
|
|
189
|
+
mv "${temp_file}" "${destination_file}"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
cache_write_meta() {
|
|
193
|
+
local key="$1"
|
|
194
|
+
local fingerprint="$2"
|
|
195
|
+
local item_count="$3"
|
|
196
|
+
local refresh_status="${4:-}"
|
|
197
|
+
local generation="${5:-}"
|
|
198
|
+
local last_error_at="${6:-}"
|
|
199
|
+
local last_error="${7:-}"
|
|
200
|
+
local created_at
|
|
201
|
+
local created_epoch
|
|
202
|
+
local meta_key
|
|
203
|
+
local meta_file
|
|
204
|
+
local temp_meta
|
|
205
|
+
|
|
206
|
+
created_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
207
|
+
created_epoch="$(date +%s)"
|
|
208
|
+
meta_key="$(cache_meta_key "${key}")"
|
|
209
|
+
meta_file="$(cache_path_for_key "${meta_key}")"
|
|
210
|
+
temp_meta="$(mktemp "${SESSION_TMP_ROOT}/meta.XXXXXX")"
|
|
211
|
+
|
|
212
|
+
{
|
|
213
|
+
printf "format_version=%s\n" "${CACHE_FORMAT_VERSION}"
|
|
214
|
+
printf "created_at=%s\n" "${created_at}"
|
|
215
|
+
printf "created_epoch=%s\n" "${created_epoch}"
|
|
216
|
+
printf "fingerprint=%s\n" "${fingerprint}"
|
|
217
|
+
printf "item_count=%s\n" "${item_count}"
|
|
218
|
+
if [[ -n "${refresh_status}" ]]; then
|
|
219
|
+
printf "refresh_status=%s\n" "${refresh_status}"
|
|
220
|
+
fi
|
|
221
|
+
if [[ -n "${generation}" ]]; then
|
|
222
|
+
printf "generation=%s\n" "${generation}"
|
|
223
|
+
fi
|
|
224
|
+
if [[ -n "${last_error_at}" ]]; then
|
|
225
|
+
printf "last_error_at=%s\n" "${last_error_at}"
|
|
226
|
+
fi
|
|
227
|
+
if [[ -n "${last_error}" ]]; then
|
|
228
|
+
printf "last_error=%s\n" "${last_error}"
|
|
229
|
+
fi
|
|
230
|
+
} >"${temp_meta}"
|
|
231
|
+
|
|
232
|
+
cache_atomic_write_from_file "${temp_meta}" "${meta_file}"
|
|
233
|
+
rm -f "${temp_meta}"
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
cache_store_key_from_file() {
|
|
237
|
+
local key="$1"
|
|
238
|
+
local fingerprint="$2"
|
|
239
|
+
local source_file="$3"
|
|
240
|
+
local refresh_status="${4:-}"
|
|
241
|
+
local generation="${5:-}"
|
|
242
|
+
local last_error_at="${6:-}"
|
|
243
|
+
local last_error="${7:-}"
|
|
244
|
+
local cache_file
|
|
245
|
+
local item_count
|
|
246
|
+
|
|
247
|
+
cache_file="$(cache_path_for_key "${key}")"
|
|
248
|
+
item_count="$(awk 'END { print NR + 0 }' "${source_file}")"
|
|
249
|
+
|
|
250
|
+
cache_atomic_write_from_file "${source_file}" "${cache_file}"
|
|
251
|
+
cache_write_meta "${key}" "${fingerprint}" "${item_count}" "${refresh_status}" "${generation}" "${last_error_at}" "${last_error}"
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
cache_meta_value_for_key() {
|
|
255
|
+
local key="$1"
|
|
256
|
+
local field_name="$2"
|
|
257
|
+
local meta_file
|
|
258
|
+
|
|
259
|
+
meta_file="$(cache_path_for_key "$(cache_meta_key "${key}")")"
|
|
260
|
+
if [[ ! -r "${meta_file}" ]]; then
|
|
261
|
+
return 1
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
awk -F'=' -v key="${field_name}" '$1 == key { value=substr($0, index($0, "=") + 1); print value; exit }' "${meta_file}"
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
cache_is_fresh_with_ttl() {
|
|
268
|
+
local key="$1"
|
|
269
|
+
local ttl_seconds="$2"
|
|
270
|
+
local created_epoch
|
|
271
|
+
local now_epoch
|
|
272
|
+
local age_seconds
|
|
273
|
+
|
|
274
|
+
if ! [[ "${ttl_seconds}" =~ ^[0-9]+$ ]]; then
|
|
275
|
+
return 1
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
if [[ "${ttl_seconds}" -eq 0 ]]; then
|
|
279
|
+
return 1
|
|
280
|
+
fi
|
|
281
|
+
|
|
282
|
+
created_epoch="$(cache_meta_value_for_key "${key}" "created_epoch" 2>/dev/null || true)"
|
|
283
|
+
if ! [[ "${created_epoch}" =~ ^[0-9]+$ ]]; then
|
|
284
|
+
return 1
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
now_epoch="$(date +%s)"
|
|
288
|
+
if ! [[ "${now_epoch}" =~ ^[0-9]+$ ]]; then
|
|
289
|
+
return 1
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
age_seconds=$((now_epoch - created_epoch))
|
|
293
|
+
if [[ "${age_seconds}" -lt 0 ]]; then
|
|
294
|
+
return 1
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
[[ "${age_seconds}" -lt "${ttl_seconds}" ]]
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
cache_emit_query_rows_if_valid() {
|
|
301
|
+
local cache_file="$1"
|
|
302
|
+
|
|
303
|
+
[[ -s "${cache_file}" ]] || return 1
|
|
304
|
+
|
|
305
|
+
if ! awk -F'\t' 'NF >= 2 && $1 != "" { next } { exit 1 } END { if (NR == 0) exit 1 }' "${cache_file}" >/dev/null 2>&1; then
|
|
306
|
+
return 1
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
awk -F'\t' 'NF >= 2 && $1 != "" { desc=$2; if (desc == "") desc="-"; print $1 "\t" desc }' "${cache_file}"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
bun_generation_state_key() {
|
|
313
|
+
local key="$1"
|
|
314
|
+
printf "state/%s.generation" "${key}"
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
bun_generation_read() {
|
|
318
|
+
local key="$1"
|
|
319
|
+
local state_file
|
|
320
|
+
local current="0"
|
|
321
|
+
|
|
322
|
+
state_file="$(cache_path_for_key "$(bun_generation_state_key "${key}")")"
|
|
323
|
+
if [[ -r "${state_file}" ]]; then
|
|
324
|
+
current="$(awk 'NR == 1 { print $1; exit }' "${state_file}")"
|
|
325
|
+
fi
|
|
326
|
+
|
|
327
|
+
if ! [[ "${current}" =~ ^[0-9]+$ ]]; then
|
|
328
|
+
current="0"
|
|
329
|
+
fi
|
|
330
|
+
|
|
331
|
+
printf "%s" "${current}"
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
bun_generation_write() {
|
|
335
|
+
local key="$1"
|
|
336
|
+
local generation="$2"
|
|
337
|
+
local state_key
|
|
338
|
+
local state_file
|
|
339
|
+
local temp_file
|
|
340
|
+
|
|
341
|
+
state_key="$(bun_generation_state_key "${key}")"
|
|
342
|
+
state_file="$(cache_path_for_key "${state_key}")"
|
|
343
|
+
temp_file="$(mktemp "${SESSION_TMP_ROOT}/bun-generation.XXXXXX")"
|
|
344
|
+
printf "%s\n" "${generation}" >"${temp_file}"
|
|
345
|
+
cache_atomic_write_from_file "${temp_file}" "${state_file}"
|
|
346
|
+
rm -f "${temp_file}"
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
bun_generation_next() {
|
|
350
|
+
local key="$1"
|
|
351
|
+
local current
|
|
352
|
+
local next
|
|
353
|
+
|
|
354
|
+
current="$(bun_generation_read "${key}")"
|
|
355
|
+
next=$((current + 1))
|
|
356
|
+
bun_generation_write "${key}" "${next}"
|
|
357
|
+
printf "%s" "${next}"
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
bun_refresh_idle_seconds() {
|
|
361
|
+
local idle_seconds="${FPF_BUN_REFRESH_IDLE:-0.12}"
|
|
362
|
+
if ! [[ "${idle_seconds}" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
363
|
+
idle_seconds="0.12"
|
|
364
|
+
fi
|
|
365
|
+
printf "%s" "${idle_seconds}"
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
bun_emit_refresh_failure_meta() {
|
|
369
|
+
local key="$1"
|
|
370
|
+
local fingerprint="$2"
|
|
371
|
+
local generation="$3"
|
|
372
|
+
local last_error="$4"
|
|
373
|
+
local cache_file
|
|
374
|
+
local item_count="0"
|
|
375
|
+
local last_error_at
|
|
376
|
+
|
|
377
|
+
cache_file="$(cache_path_for_key "${key}")"
|
|
378
|
+
if [[ -s "${cache_file}" ]]; then
|
|
379
|
+
item_count="$(awk 'END { print NR + 0 }' "${cache_file}")"
|
|
380
|
+
fi
|
|
381
|
+
|
|
382
|
+
last_error_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
383
|
+
cache_write_meta "${key}" "${fingerprint}" "${item_count}" "error" "${generation}" "${last_error_at}" "${last_error}"
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
bun_try_hot_reload_after_refresh() {
|
|
387
|
+
local query="$1"
|
|
388
|
+
|
|
389
|
+
if [[ -n "${FPF_BUN_REFRESH_MANAGER_OVERRIDE:-}" || -n "${FPF_BUN_REFRESH_FALLBACK_FILE:-}" ]]; then
|
|
390
|
+
FPF_BUN_SKIP_REFRESH_SCHEDULE=1 \
|
|
391
|
+
FPF_IPC_MANAGER_OVERRIDE="${FPF_BUN_REFRESH_MANAGER_OVERRIDE:-}" \
|
|
392
|
+
FPF_IPC_FALLBACK_FILE="${FPF_BUN_REFRESH_FALLBACK_FILE:-}" \
|
|
393
|
+
run_ipc_reload_action "${query}" || true
|
|
394
|
+
fi
|
|
395
|
+
|
|
396
|
+
if [[ -n "${FPF_TEST_CACHE_REFRESH_SIGNAL_FILE:-}" ]] && command_exists fpf-refresh-signal; then
|
|
397
|
+
fpf-refresh-signal >/dev/null 2>&1 || true
|
|
398
|
+
fi
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
bun_run_refresh_worker() {
|
|
402
|
+
local manager="$1"
|
|
403
|
+
local query="$2"
|
|
404
|
+
local flags="$3"
|
|
405
|
+
local key="$4"
|
|
406
|
+
local fingerprint="$5"
|
|
407
|
+
local generation="$6"
|
|
408
|
+
local output_tmp
|
|
409
|
+
|
|
410
|
+
sleep "$(bun_refresh_idle_seconds)"
|
|
411
|
+
|
|
412
|
+
if [[ "${generation}" != "$(bun_generation_read "${key}")" ]]; then
|
|
413
|
+
return 0
|
|
414
|
+
fi
|
|
415
|
+
|
|
416
|
+
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/bun-refresh.XXXXXX")"
|
|
417
|
+
if ! manager_bun_search_entries_strict "${query}" >"${output_tmp}"; then
|
|
418
|
+
rm -f "${output_tmp}"
|
|
419
|
+
bun_emit_refresh_failure_meta "${key}" "${fingerprint}" "${generation}" "bun_search_failed"
|
|
420
|
+
send_fzf_prompt_action "Search> " || true
|
|
421
|
+
return 1
|
|
422
|
+
fi
|
|
423
|
+
|
|
424
|
+
if [[ "${generation}" != "$(bun_generation_read "${key}")" ]]; then
|
|
425
|
+
rm -f "${output_tmp}"
|
|
426
|
+
return 0
|
|
427
|
+
fi
|
|
428
|
+
|
|
429
|
+
cache_store_key_from_file "${key}" "${fingerprint}" "${output_tmp}" "success" "${generation}"
|
|
430
|
+
rm -f "${output_tmp}"
|
|
431
|
+
bun_try_hot_reload_after_refresh "${query}"
|
|
432
|
+
return 0
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
start_bun_refresh_worker_async() {
|
|
436
|
+
local manager="$1"
|
|
437
|
+
local query="$2"
|
|
438
|
+
local flags="$3"
|
|
439
|
+
local key="$4"
|
|
440
|
+
local fingerprint="$5"
|
|
441
|
+
local generation="$6"
|
|
442
|
+
local fallback_file="$7"
|
|
443
|
+
local manager_override="$8"
|
|
444
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
445
|
+
|
|
446
|
+
if [[ "${script_path}" != /* ]]; then
|
|
447
|
+
script_path="$(pwd)/${script_path}"
|
|
448
|
+
fi
|
|
449
|
+
|
|
450
|
+
FPF_BUN_REFRESH_FLAGS="${flags}" \
|
|
451
|
+
FPF_BUN_REFRESH_KEY="${key}" \
|
|
452
|
+
FPF_BUN_REFRESH_FINGERPRINT="${fingerprint}" \
|
|
453
|
+
FPF_BUN_REFRESH_GENERATION="${generation}" \
|
|
454
|
+
FPF_BUN_REFRESH_FALLBACK_FILE="${fallback_file}" \
|
|
455
|
+
FPF_BUN_REFRESH_MANAGER_OVERRIDE="${manager_override}" \
|
|
456
|
+
"${script_path}" --bun-refresh-worker --manager "${manager}" -- "${query}" >/dev/null 2>&1 &
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
build_apt_catalog_entries() {
|
|
460
|
+
apt-cache dumpavail 2>/dev/null |
|
|
461
|
+
awk '
|
|
462
|
+
function flush_entry() {
|
|
463
|
+
if (pkg == "") {
|
|
464
|
+
return
|
|
465
|
+
}
|
|
466
|
+
desc_out = desc
|
|
467
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "", desc_out)
|
|
468
|
+
if (desc_out == "") {
|
|
469
|
+
desc_out = "-"
|
|
470
|
+
}
|
|
471
|
+
print pkg "\t" desc_out
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/^Package:[[:space:]]*/ {
|
|
475
|
+
flush_entry()
|
|
476
|
+
pkg = $0
|
|
477
|
+
sub(/^Package:[[:space:]]*/, "", pkg)
|
|
478
|
+
desc = ""
|
|
479
|
+
next
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/^Description:[[:space:]]*/ {
|
|
483
|
+
desc = $0
|
|
484
|
+
sub(/^Description:[[:space:]]*/, "", desc)
|
|
485
|
+
next
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/^[[:space:]]+/ {
|
|
489
|
+
if (desc != "") {
|
|
490
|
+
line = $0
|
|
491
|
+
sub(/^[[:space:]]+/, "", line)
|
|
492
|
+
if (line != "") {
|
|
493
|
+
desc = desc " " line
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
next
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/^$/ {
|
|
500
|
+
flush_entry()
|
|
501
|
+
pkg = ""
|
|
502
|
+
desc = ""
|
|
503
|
+
next
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
END {
|
|
507
|
+
flush_entry()
|
|
508
|
+
}
|
|
509
|
+
' |
|
|
510
|
+
awk -F'\t' 'NF >= 1 && $1 != "" { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' |
|
|
511
|
+
awk -F'\t' '!seen[$1]++'
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
build_brew_catalog_entries() {
|
|
515
|
+
{
|
|
516
|
+
brew formulae 2>/dev/null || true
|
|
517
|
+
brew casks 2>/dev/null || true
|
|
518
|
+
} |
|
|
519
|
+
awk 'NF >= 1 && $1 != "" { print $1 "\t-" }' |
|
|
520
|
+
awk -F'\t' '!seen[$1]++'
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
ensure_search_catalog_cache() {
|
|
524
|
+
local manager="$1"
|
|
525
|
+
local cache_fingerprint_value
|
|
526
|
+
local cache_key
|
|
527
|
+
local cache_file
|
|
528
|
+
local output_tmp
|
|
529
|
+
|
|
530
|
+
initialize_cache_root
|
|
531
|
+
|
|
532
|
+
cache_fingerprint_value="$(cache_search_catalog_fingerprint "${manager}")"
|
|
533
|
+
cache_key="$(cache_search_catalog_key "${manager}" "${cache_fingerprint_value}")"
|
|
534
|
+
cache_file="$(cache_path_for_key "${cache_key}")"
|
|
535
|
+
|
|
536
|
+
if [[ -s "${cache_file}" ]]; then
|
|
537
|
+
return 0
|
|
538
|
+
fi
|
|
539
|
+
|
|
540
|
+
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/search-catalog.XXXXXX")"
|
|
541
|
+
|
|
542
|
+
case "${manager}" in
|
|
543
|
+
apt)
|
|
544
|
+
build_apt_catalog_entries >"${output_tmp}" || true
|
|
545
|
+
;;
|
|
546
|
+
brew)
|
|
547
|
+
build_brew_catalog_entries >"${output_tmp}" || true
|
|
548
|
+
;;
|
|
549
|
+
*)
|
|
550
|
+
rm -f "${output_tmp}"
|
|
551
|
+
return 1
|
|
552
|
+
;;
|
|
553
|
+
esac
|
|
554
|
+
|
|
555
|
+
if [[ -s "${output_tmp}" ]]; then
|
|
556
|
+
cache_store_key_from_file "${cache_key}" "${cache_fingerprint_value}" "${output_tmp}"
|
|
557
|
+
rm -f "${output_tmp}"
|
|
558
|
+
return 0
|
|
559
|
+
fi
|
|
560
|
+
|
|
561
|
+
rm -f "${output_tmp}"
|
|
562
|
+
return 1
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
search_entries_from_catalog_cache() {
|
|
566
|
+
local manager="$1"
|
|
567
|
+
local query="$2"
|
|
568
|
+
local cache_fingerprint_value
|
|
569
|
+
local cache_key
|
|
570
|
+
local cache_file
|
|
571
|
+
|
|
572
|
+
initialize_cache_root
|
|
573
|
+
|
|
574
|
+
cache_fingerprint_value="$(cache_search_catalog_fingerprint "${manager}")"
|
|
575
|
+
cache_key="$(cache_search_catalog_key "${manager}" "${cache_fingerprint_value}")"
|
|
576
|
+
cache_file="$(cache_path_for_key "${cache_key}")"
|
|
577
|
+
|
|
578
|
+
if [[ ! -s "${cache_file}" ]]; then
|
|
579
|
+
return 1
|
|
580
|
+
fi
|
|
581
|
+
|
|
582
|
+
awk -F'\t' -v query="${query}" '
|
|
583
|
+
BEGIN {
|
|
584
|
+
normalized = tolower(query)
|
|
585
|
+
token_count = split(normalized, raw_tokens, /[[:space:]]+/)
|
|
586
|
+
token_index = 0
|
|
587
|
+
for (i = 1; i <= token_count; i++) {
|
|
588
|
+
if (raw_tokens[i] != "") {
|
|
589
|
+
token_index++
|
|
590
|
+
tokens[token_index] = raw_tokens[i]
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
{
|
|
595
|
+
haystack = tolower($1 " " $2)
|
|
596
|
+
matched = 1
|
|
597
|
+
for (i = 1; i <= token_index; i++) {
|
|
598
|
+
if (index(haystack, tokens[i]) == 0) {
|
|
599
|
+
matched = 0
|
|
600
|
+
break
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (matched) {
|
|
604
|
+
desc = $2
|
|
605
|
+
if (desc == "") {
|
|
606
|
+
desc = "-"
|
|
607
|
+
}
|
|
608
|
+
print $1 "\t" desc
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
' "${cache_file}" || return 1
|
|
612
|
+
}
|
|
613
|
+
|
|
33
614
|
initialize_session_tmp_root() {
|
|
34
615
|
if [[ -n "${SESSION_TMP_ROOT}" ]]; then
|
|
35
616
|
return
|
|
36
617
|
fi
|
|
37
618
|
|
|
38
|
-
|
|
619
|
+
if [[ -n "${FPF_SESSION_TMP_ROOT:-}" ]]; then
|
|
620
|
+
SESSION_TMP_ROOT="${FPF_SESSION_TMP_ROOT}"
|
|
621
|
+
mkdir -p "${SESSION_TMP_ROOT}"
|
|
622
|
+
else
|
|
623
|
+
SESSION_TMP_ROOT="$(mktemp -d "${TMP_ROOT}/session.XXXXXX")"
|
|
624
|
+
fi
|
|
39
625
|
HELP_FILE="${SESSION_TMP_ROOT}/help"
|
|
40
626
|
KBINDS_FILE="${SESSION_TMP_ROOT}/keybinds"
|
|
41
627
|
}
|
|
42
628
|
|
|
629
|
+
run_preview_manager_output() {
|
|
630
|
+
local manager="$1"
|
|
631
|
+
local package="$2"
|
|
632
|
+
|
|
633
|
+
case "${manager}" in
|
|
634
|
+
apt)
|
|
635
|
+
apt-cache show "${package}" 2>/dev/null || true
|
|
636
|
+
printf "\n"
|
|
637
|
+
dpkg -L "${package}" 2>/dev/null || true
|
|
638
|
+
;;
|
|
639
|
+
dnf)
|
|
640
|
+
dnf info "${package}" 2>/dev/null || true
|
|
641
|
+
printf "\n"
|
|
642
|
+
rpm -ql "${package}" 2>/dev/null || true
|
|
643
|
+
;;
|
|
644
|
+
pacman)
|
|
645
|
+
pacman -Si "${package}" 2>/dev/null || true
|
|
646
|
+
printf "\n"
|
|
647
|
+
pacman -Fl "${package}" 2>/dev/null | awk '{print $2}' || true
|
|
648
|
+
;;
|
|
649
|
+
zypper)
|
|
650
|
+
zypper --non-interactive info "${package}" 2>/dev/null || true
|
|
651
|
+
;;
|
|
652
|
+
emerge)
|
|
653
|
+
emerge --search --color=n "${package}" 2>/dev/null || true
|
|
654
|
+
;;
|
|
655
|
+
brew)
|
|
656
|
+
brew info "${package}" 2>/dev/null || true
|
|
657
|
+
;;
|
|
658
|
+
winget)
|
|
659
|
+
winget show --id "${package}" --exact --source winget --accept-source-agreements --disable-interactivity 2>/dev/null || true
|
|
660
|
+
;;
|
|
661
|
+
choco)
|
|
662
|
+
choco info "${package}" 2>/dev/null || true
|
|
663
|
+
;;
|
|
664
|
+
scoop)
|
|
665
|
+
scoop info "${package}" 2>/dev/null || true
|
|
666
|
+
;;
|
|
667
|
+
snap)
|
|
668
|
+
snap info "${package}" 2>/dev/null || true
|
|
669
|
+
;;
|
|
670
|
+
flatpak)
|
|
671
|
+
flatpak info "${package}" 2>/dev/null || flatpak remote-info flathub "${package}" 2>/dev/null || true
|
|
672
|
+
;;
|
|
673
|
+
npm)
|
|
674
|
+
npm view "${package}" 2>/dev/null || true
|
|
675
|
+
;;
|
|
676
|
+
bun)
|
|
677
|
+
bun info "${package}" 2>/dev/null || npm view "${package}" 2>/dev/null || true
|
|
678
|
+
;;
|
|
679
|
+
esac
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
run_preview_item_action() {
|
|
683
|
+
local manager="$1"
|
|
684
|
+
local package="$2"
|
|
685
|
+
local cache_dir="${SESSION_TMP_ROOT}/preview-cache"
|
|
686
|
+
local cache_key=""
|
|
687
|
+
local cache_file=""
|
|
688
|
+
local temp_file=""
|
|
689
|
+
|
|
690
|
+
[[ -n "${manager}" && -n "${package}" ]] || return 0
|
|
691
|
+
|
|
692
|
+
mkdir -p "${cache_dir}"
|
|
693
|
+
cache_key="$(cache_cksum "${manager}|${package}")"
|
|
694
|
+
cache_file="${cache_dir}/${manager}.${cache_key}.txt"
|
|
695
|
+
|
|
696
|
+
if [[ -f "${cache_file}" ]]; then
|
|
697
|
+
cat "${cache_file}"
|
|
698
|
+
return 0
|
|
699
|
+
fi
|
|
700
|
+
|
|
701
|
+
temp_file="$(mktemp "${SESSION_TMP_ROOT}/preview.XXXXXX")"
|
|
702
|
+
run_preview_manager_output "${manager}" "${package}" >"${temp_file}"
|
|
703
|
+
mv -f "${temp_file}" "${cache_file}"
|
|
704
|
+
cat "${cache_file}"
|
|
705
|
+
}
|
|
706
|
+
|
|
43
707
|
cleanup_session_tmp_root() {
|
|
44
708
|
if [[ -n "${SESSION_TMP_ROOT}" && -d "${SESSION_TMP_ROOT}" ]]; then
|
|
45
709
|
rm -rf "${SESSION_TMP_ROOT}"
|
|
@@ -124,6 +788,22 @@ manager_command_ready() {
|
|
|
124
788
|
esac
|
|
125
789
|
}
|
|
126
790
|
|
|
791
|
+
flatpak_has_any_remotes() {
|
|
792
|
+
if ! manager_command_ready flatpak; then
|
|
793
|
+
return 1
|
|
794
|
+
fi
|
|
795
|
+
|
|
796
|
+
if flatpak remotes --columns=name 2>/dev/null | awk 'NF > 0 { found=1; exit } END { exit (found ? 0 : 1) }'; then
|
|
797
|
+
return 0
|
|
798
|
+
fi
|
|
799
|
+
|
|
800
|
+
if flatpak remote-list --columns=name 2>/dev/null | awk 'NF > 0 { found=1; exit } END { exit (found ? 0 : 1) }'; then
|
|
801
|
+
return 0
|
|
802
|
+
fi
|
|
803
|
+
|
|
804
|
+
return 1
|
|
805
|
+
}
|
|
806
|
+
|
|
127
807
|
manager_can_install_fzf() {
|
|
128
808
|
local manager="$1"
|
|
129
809
|
case "${manager}" in
|
|
@@ -214,7 +894,7 @@ ensure_fzf() {
|
|
|
214
894
|
local candidates=()
|
|
215
895
|
local manager
|
|
216
896
|
|
|
217
|
-
if command_exists fzf; then
|
|
897
|
+
if [[ "${FPF_TEST_FORCE_FZF_MISSING:-0}" != "1" ]] && command_exists fzf; then
|
|
218
898
|
return
|
|
219
899
|
fi
|
|
220
900
|
|
|
@@ -533,6 +1213,18 @@ parse_args() {
|
|
|
533
1213
|
--feed-search)
|
|
534
1214
|
ACTION="feed-search"
|
|
535
1215
|
;;
|
|
1216
|
+
--ipc-reload)
|
|
1217
|
+
ACTION="ipc-reload"
|
|
1218
|
+
;;
|
|
1219
|
+
--ipc-query-notify)
|
|
1220
|
+
ACTION="ipc-query-notify"
|
|
1221
|
+
;;
|
|
1222
|
+
--preview-item)
|
|
1223
|
+
ACTION="preview-item"
|
|
1224
|
+
;;
|
|
1225
|
+
--bun-refresh-worker)
|
|
1226
|
+
ACTION="bun-refresh-worker"
|
|
1227
|
+
;;
|
|
536
1228
|
-ap|--apt)
|
|
537
1229
|
MANAGER_OVERRIDE="apt"
|
|
538
1230
|
;;
|
|
@@ -806,7 +1498,59 @@ exact_match_entry() {
|
|
|
806
1498
|
done < <(exact_query_candidates "${query}" | awk '!seen[$0]++')
|
|
807
1499
|
}
|
|
808
1500
|
|
|
809
|
-
|
|
1501
|
+
manager_bun_search_entries_strict() {
|
|
1502
|
+
local query="$1"
|
|
1503
|
+
local effective_query="${query}"
|
|
1504
|
+
local line_limit=0
|
|
1505
|
+
local query_line_limit=40
|
|
1506
|
+
local effective_limit=0
|
|
1507
|
+
local bun_search_file
|
|
1508
|
+
|
|
1509
|
+
if [[ -z "${query}" ]]; then
|
|
1510
|
+
line_limit="${FPF_NO_QUERY_RESULT_LIMIT:-120}"
|
|
1511
|
+
else
|
|
1512
|
+
query_line_limit="${FPF_QUERY_PER_MANAGER_LIMIT:-40}"
|
|
1513
|
+
fi
|
|
1514
|
+
|
|
1515
|
+
if ! [[ "${line_limit}" =~ ^[0-9]+$ ]]; then
|
|
1516
|
+
line_limit=0
|
|
1517
|
+
fi
|
|
1518
|
+
|
|
1519
|
+
if ! [[ "${query_line_limit}" =~ ^[0-9]+$ ]]; then
|
|
1520
|
+
query_line_limit=40
|
|
1521
|
+
fi
|
|
1522
|
+
|
|
1523
|
+
if [[ "${line_limit}" -gt 0 ]]; then
|
|
1524
|
+
effective_limit="${line_limit}"
|
|
1525
|
+
else
|
|
1526
|
+
effective_limit="${query_line_limit}"
|
|
1527
|
+
fi
|
|
1528
|
+
|
|
1529
|
+
if [[ -z "${effective_query}" ]]; then
|
|
1530
|
+
effective_query="aa"
|
|
1531
|
+
fi
|
|
1532
|
+
|
|
1533
|
+
bun_search_file="$(mktemp "${SESSION_TMP_ROOT}/bun-search-strict.XXXXXX")"
|
|
1534
|
+
if ! bun search "${effective_query}" >"${bun_search_file}" 2>/dev/null; then
|
|
1535
|
+
rm -f "${bun_search_file}"
|
|
1536
|
+
return 1
|
|
1537
|
+
fi
|
|
1538
|
+
|
|
1539
|
+
{
|
|
1540
|
+
awk 'NR > 1 && NF > 0 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }' "${bun_search_file}"
|
|
1541
|
+
exact_match_entry "bun" "${query}"
|
|
1542
|
+
} | awk -F'\t' 'NF >= 1 { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' | awk -F'\t' '!seen[$1]++' | {
|
|
1543
|
+
if [[ "${effective_limit}" -gt 0 ]]; then
|
|
1544
|
+
awk -v limit="${effective_limit}" 'NR <= limit'
|
|
1545
|
+
else
|
|
1546
|
+
cat
|
|
1547
|
+
fi
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
rm -f "${bun_search_file}"
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
manager_search_entries_uncached() {
|
|
810
1554
|
local manager="$1"
|
|
811
1555
|
local query="$2"
|
|
812
1556
|
local effective_query="${query}"
|
|
@@ -856,8 +1600,12 @@ manager_search_entries() {
|
|
|
856
1600
|
|
|
857
1601
|
case "${manager}" in
|
|
858
1602
|
apt)
|
|
859
|
-
|
|
860
|
-
|
|
1603
|
+
if ensure_search_catalog_cache "${manager}"; then
|
|
1604
|
+
search_entries_from_catalog_cache "${manager}" "${effective_query}" || true
|
|
1605
|
+
else
|
|
1606
|
+
apt-cache search -- "${effective_query}" 2>/dev/null |
|
|
1607
|
+
awk -F' - ' '{ name=$1; desc=$2; gsub(/^[[:space:]]+|[[:space:]]+$/, "", name); if (desc == "") desc="-"; print name "\t" desc }'
|
|
1608
|
+
fi
|
|
861
1609
|
;;
|
|
862
1610
|
dnf)
|
|
863
1611
|
local pattern="*"
|
|
@@ -914,11 +1662,18 @@ manager_search_entries() {
|
|
|
914
1662
|
'
|
|
915
1663
|
;;
|
|
916
1664
|
brew)
|
|
917
|
-
{
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1665
|
+
if ensure_search_catalog_cache "${manager}"; then
|
|
1666
|
+
{
|
|
1667
|
+
search_entries_from_catalog_cache "${manager}" "${effective_query}" || true
|
|
1668
|
+
exact_match_entry "${manager}" "${query}"
|
|
1669
|
+
}
|
|
1670
|
+
else
|
|
1671
|
+
{
|
|
1672
|
+
brew search "${effective_query}" 2>/dev/null |
|
|
1673
|
+
awk 'NF > 0 && $1 != "==>" { print $1 "\t-" }'
|
|
1674
|
+
exact_match_entry "${manager}" "${query}"
|
|
1675
|
+
}
|
|
1676
|
+
fi
|
|
922
1677
|
;;
|
|
923
1678
|
winget)
|
|
924
1679
|
winget search "${effective_query}" --source winget --accept-source-agreements --disable-interactivity 2>/dev/null |
|
|
@@ -1017,6 +1772,83 @@ manager_search_entries() {
|
|
|
1017
1772
|
} || true
|
|
1018
1773
|
}
|
|
1019
1774
|
|
|
1775
|
+
manager_search_entries() {
|
|
1776
|
+
local manager="$1"
|
|
1777
|
+
local query="$2"
|
|
1778
|
+
local query_cache_enabled="${FPF_ENABLE_QUERY_CACHE:-0}"
|
|
1779
|
+
local bun_cache_ttl="${FPF_BUN_QUERY_CACHE_TTL:-900}"
|
|
1780
|
+
local flags
|
|
1781
|
+
local key
|
|
1782
|
+
local fingerprint
|
|
1783
|
+
local cache_file
|
|
1784
|
+
local output_tmp
|
|
1785
|
+
local generation
|
|
1786
|
+
local should_async_refresh=0
|
|
1787
|
+
|
|
1788
|
+
initialize_cache_root
|
|
1789
|
+
|
|
1790
|
+
flags="$(query_cache_flags)"
|
|
1791
|
+
|
|
1792
|
+
if ! [[ "${bun_cache_ttl}" =~ ^[0-9]+$ ]]; then
|
|
1793
|
+
bun_cache_ttl=900
|
|
1794
|
+
fi
|
|
1795
|
+
|
|
1796
|
+
if [[ "${manager}" == "bun" ]]; then
|
|
1797
|
+
query_cache_enabled="1"
|
|
1798
|
+
fi
|
|
1799
|
+
|
|
1800
|
+
key="$(cache_query_key "${manager}" "${query}" "${flags}")"
|
|
1801
|
+
fingerprint="$(cache_fingerprint "${manager}" "${query}" "${flags}")"
|
|
1802
|
+
cache_file="$(cache_path_for_key "${key}")"
|
|
1803
|
+
|
|
1804
|
+
if [[ "${manager}" == "bun" && ( "${ACTION}" == "feed-search" || "${ACTION}" == "ipc-query-notify" ) ]]; then
|
|
1805
|
+
if [[ -s "${cache_file}" ]]; then
|
|
1806
|
+
cache_emit_query_rows_if_valid "${cache_file}" || true
|
|
1807
|
+
fi
|
|
1808
|
+
|
|
1809
|
+
if cache_is_fresh_with_ttl "${key}" "${bun_cache_ttl}"; then
|
|
1810
|
+
return
|
|
1811
|
+
fi
|
|
1812
|
+
|
|
1813
|
+
generation="$(bun_generation_next "${key}")"
|
|
1814
|
+
if [[ -n "${FZF_PORT:-}" && "${FPF_BUN_SKIP_REFRESH_SCHEDULE:-0}" != "1" ]]; then
|
|
1815
|
+
should_async_refresh=1
|
|
1816
|
+
fi
|
|
1817
|
+
|
|
1818
|
+
if [[ "${FPF_BUN_TEST_SYNC_REFRESH:-0}" == "1" ]]; then
|
|
1819
|
+
should_async_refresh=0
|
|
1820
|
+
fi
|
|
1821
|
+
|
|
1822
|
+
if [[ "${should_async_refresh}" -eq 1 ]]; then
|
|
1823
|
+
start_bun_refresh_worker_async "${manager}" "${query}" "${flags}" "${key}" "${fingerprint}" "${generation}" "${FPF_IPC_FALLBACK_FILE:-}" "${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
1824
|
+
return
|
|
1825
|
+
fi
|
|
1826
|
+
|
|
1827
|
+
bun_run_refresh_worker "${manager}" "${query}" "${flags}" "${key}" "${fingerprint}" "${generation}" || true
|
|
1828
|
+
if [[ -s "${cache_file}" ]]; then
|
|
1829
|
+
cache_emit_query_rows_if_valid "${cache_file}" || true
|
|
1830
|
+
fi
|
|
1831
|
+
return
|
|
1832
|
+
fi
|
|
1833
|
+
|
|
1834
|
+
if [[ "${query_cache_enabled}" == "1" && -s "${cache_file}" ]]; then
|
|
1835
|
+
if [[ "${manager}" != "bun" ]] || cache_is_fresh_with_ttl "${key}" "${bun_cache_ttl}"; then
|
|
1836
|
+
cat "${cache_file}"
|
|
1837
|
+
return
|
|
1838
|
+
fi
|
|
1839
|
+
fi
|
|
1840
|
+
|
|
1841
|
+
output_tmp="$(mktemp "${SESSION_TMP_ROOT}/query-cache.XXXXXX")"
|
|
1842
|
+
manager_search_entries_uncached "${manager}" "${query}" >"${output_tmp}" || true
|
|
1843
|
+
|
|
1844
|
+
if [[ "${query_cache_enabled}" == "1" ]]; then
|
|
1845
|
+
cache_store_key_from_file "${key}" "${fingerprint}" "${output_tmp}"
|
|
1846
|
+
fi
|
|
1847
|
+
|
|
1848
|
+
cat "${output_tmp}"
|
|
1849
|
+
rm -f "${output_tmp}"
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1020
1852
|
manager_installed_entries() {
|
|
1021
1853
|
local manager="$1"
|
|
1022
1854
|
|
|
@@ -1137,34 +1969,35 @@ manager_installed_entries() {
|
|
|
1137
1969
|
;;
|
|
1138
1970
|
bun)
|
|
1139
1971
|
{
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1972
|
+
local bun_pm_file
|
|
1973
|
+
bun_pm_file="$(mktemp "${SESSION_TMP_ROOT}/bun-pm.XXXXXX")"
|
|
1974
|
+
if bun pm ls --global >"${bun_pm_file}" 2>/dev/null; then
|
|
1975
|
+
awk '
|
|
1976
|
+
NR > 1 {
|
|
1977
|
+
line = $0
|
|
1978
|
+
gsub(/\r/, "", line)
|
|
1979
|
+
sub(/^[[:space:]]*[^[:alnum:]@]*/, "", line)
|
|
1980
|
+
sub(/^[[:space:]]+/, "", line)
|
|
1981
|
+
sub(/[[:space:]]+$/, "", line)
|
|
1982
|
+
|
|
1983
|
+
if (line == "") next
|
|
1984
|
+
if (line ~ /[[:space:]]node_modules([[:space:]]|$)/) next
|
|
1985
|
+
|
|
1986
|
+
split(line, fields, /[[:space:]]+/)
|
|
1987
|
+
pkg = fields[1]
|
|
1988
|
+
if (pkg == "") next
|
|
1989
|
+
|
|
1990
|
+
pkg_copy = pkg
|
|
1991
|
+
at_count = gsub(/@/, "@", pkg_copy)
|
|
1992
|
+
if ((substr(pkg, 1, 1) == "@" && at_count >= 2) || (substr(pkg, 1, 1) != "@" && at_count >= 1)) {
|
|
1993
|
+
sub(/@[^@[:space:]]*$/, "", pkg)
|
|
1994
|
+
}
|
|
1162
1995
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
}
|
|
1996
|
+
if (pkg != "") {
|
|
1997
|
+
print pkg "\tglobal"
|
|
1166
1998
|
}
|
|
1167
|
-
|
|
1999
|
+
}
|
|
2000
|
+
' "${bun_pm_file}"
|
|
1168
2001
|
elif command_exists npm; then
|
|
1169
2002
|
npm ls -g --depth=0 --parseable 2>/dev/null |
|
|
1170
2003
|
awk '
|
|
@@ -1188,6 +2021,7 @@ manager_installed_entries() {
|
|
|
1188
2021
|
}
|
|
1189
2022
|
'
|
|
1190
2023
|
fi
|
|
2024
|
+
rm -f "${bun_pm_file}"
|
|
1191
2025
|
} || true
|
|
1192
2026
|
;;
|
|
1193
2027
|
esac | sort -u || true
|
|
@@ -1202,8 +2036,15 @@ manager_installed_names_cached() {
|
|
|
1202
2036
|
local manager="$1"
|
|
1203
2037
|
local output_file="$2"
|
|
1204
2038
|
local cache_enabled="${FPF_DISABLE_INSTALLED_CACHE:-0}"
|
|
1205
|
-
local
|
|
1206
|
-
local cache_file
|
|
2039
|
+
local cache_key
|
|
2040
|
+
local cache_file
|
|
2041
|
+
local cache_fingerprint_value
|
|
2042
|
+
|
|
2043
|
+
initialize_cache_root
|
|
2044
|
+
|
|
2045
|
+
cache_key="$(cache_catalog_key "${manager}")"
|
|
2046
|
+
cache_file="$(cache_path_for_key "${cache_key}")"
|
|
2047
|
+
cache_fingerprint_value="$(cache_fingerprint "${manager}" "" "installed")"
|
|
1207
2048
|
|
|
1208
2049
|
if [[ "${cache_enabled}" != "1" && -s "${cache_file}" ]]; then
|
|
1209
2050
|
cp "${cache_file}" "${output_file}"
|
|
@@ -1213,47 +2054,82 @@ manager_installed_names_cached() {
|
|
|
1213
2054
|
manager_installed_names "${manager}" >"${output_file}" 2>/dev/null || true
|
|
1214
2055
|
|
|
1215
2056
|
if [[ "${cache_enabled}" != "1" && -s "${output_file}" ]]; then
|
|
1216
|
-
|
|
1217
|
-
cp "${output_file}" "${cache_file}"
|
|
2057
|
+
cache_store_key_from_file "${cache_key}" "${cache_fingerprint_value}" "${output_file}"
|
|
1218
2058
|
fi
|
|
1219
2059
|
}
|
|
1220
2060
|
|
|
1221
2061
|
mark_installed_packages() {
|
|
1222
|
-
local
|
|
1223
|
-
local
|
|
1224
|
-
local output_file="$3"
|
|
2062
|
+
local source_file="$1"
|
|
2063
|
+
local output_file="$2"
|
|
1225
2064
|
local installed_file
|
|
2065
|
+
local installed_map_file
|
|
2066
|
+
local manager
|
|
1226
2067
|
|
|
1227
2068
|
if [[ "${FPF_SKIP_INSTALLED_MARKERS:-0}" == "1" ]]; then
|
|
1228
2069
|
awk -F'\t' '
|
|
1229
2070
|
{
|
|
1230
|
-
desc = $
|
|
2071
|
+
desc = $3
|
|
1231
2072
|
if (desc == "") desc = "-"
|
|
1232
|
-
print $1 "\t " desc
|
|
2073
|
+
print $1 "\t" $2 "\t " desc
|
|
1233
2074
|
}
|
|
1234
2075
|
' "${source_file}" >"${output_file}"
|
|
1235
2076
|
return
|
|
1236
2077
|
fi
|
|
1237
2078
|
|
|
1238
|
-
|
|
1239
|
-
|
|
2079
|
+
installed_map_file="$(mktemp "${SESSION_TMP_ROOT}/installed-map.XXXXXX")"
|
|
2080
|
+
: >"${installed_map_file}"
|
|
2081
|
+
|
|
2082
|
+
while IFS= read -r manager; do
|
|
2083
|
+
[[ -n "${manager}" ]] || continue
|
|
2084
|
+
installed_file="$(mktemp "${SESSION_TMP_ROOT}/installed.${manager}.XXXXXX")"
|
|
2085
|
+
manager_installed_names_cached "${manager}" "${installed_file}"
|
|
2086
|
+
if [[ -s "${installed_file}" ]]; then
|
|
2087
|
+
awk -F'\t' -v mgr="${manager}" 'NF > 0 && $1 != "" { print mgr "\t" $1 }' "${installed_file}" >>"${installed_map_file}"
|
|
2088
|
+
fi
|
|
2089
|
+
rm -f "${installed_file}"
|
|
2090
|
+
done < <(awk -F'\t' 'NF >= 1 && $1 != "" { print $1 }' "${source_file}" | awk '!seen[$0]++')
|
|
1240
2091
|
|
|
1241
2092
|
awk -F'\t' '
|
|
1242
2093
|
FILENAME == ARGV[1] {
|
|
1243
|
-
|
|
1244
|
-
|
|
2094
|
+
key = $1 "\t" $2
|
|
2095
|
+
if ($1 != "" && $2 != "") {
|
|
2096
|
+
installed[key] = 1
|
|
1245
2097
|
}
|
|
1246
2098
|
next
|
|
1247
2099
|
}
|
|
1248
2100
|
{
|
|
1249
|
-
|
|
1250
|
-
|
|
2101
|
+
key = $1 "\t" $2
|
|
2102
|
+
mark = (installed[key] ? "* " : " ")
|
|
2103
|
+
desc = $3
|
|
1251
2104
|
if (desc == "") desc = "-"
|
|
1252
|
-
print $1 "\t" mark desc
|
|
2105
|
+
print $1 "\t" $2 "\t" mark desc
|
|
1253
2106
|
}
|
|
1254
|
-
' "${
|
|
2107
|
+
' "${installed_map_file}" "${source_file}" >"${output_file}"
|
|
2108
|
+
|
|
2109
|
+
rm -f "${installed_map_file}"
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
merge_search_display_rows() {
|
|
2113
|
+
local source_file="$1"
|
|
2114
|
+
local output_file="$2"
|
|
2115
|
+
|
|
2116
|
+
if [[ ! -s "${source_file}" ]]; then
|
|
2117
|
+
: >"${output_file}"
|
|
2118
|
+
return
|
|
2119
|
+
fi
|
|
1255
2120
|
|
|
1256
|
-
|
|
2121
|
+
sort -t $'\t' -k1,1 -k2,2 -k3,3 "${source_file}" |
|
|
2122
|
+
awk -F'\t' '
|
|
2123
|
+
NF >= 2 {
|
|
2124
|
+
key = $1 "\t" $2
|
|
2125
|
+
if (seen[key]++) {
|
|
2126
|
+
next
|
|
2127
|
+
}
|
|
2128
|
+
desc = $3
|
|
2129
|
+
if (desc == "") desc = "-"
|
|
2130
|
+
print $1 "\t" $2 "\t" desc
|
|
2131
|
+
}
|
|
2132
|
+
' >"${output_file}"
|
|
1257
2133
|
}
|
|
1258
2134
|
|
|
1259
2135
|
collect_search_display_rows() {
|
|
@@ -1270,6 +2146,8 @@ collect_search_display_rows() {
|
|
|
1270
2146
|
local manager
|
|
1271
2147
|
local part_file
|
|
1272
2148
|
local gather_pid
|
|
2149
|
+
local merged_source_file
|
|
2150
|
+
local merged_marked_file
|
|
1273
2151
|
|
|
1274
2152
|
for manager in "${managers[@]-}"; do
|
|
1275
2153
|
part_file="$(mktemp "${SESSION_TMP_ROOT}/part.XXXXXX")"
|
|
@@ -1277,19 +2155,17 @@ collect_search_display_rows() {
|
|
|
1277
2155
|
|
|
1278
2156
|
(
|
|
1279
2157
|
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
1280
|
-
local_marked_file="$(mktemp "${SESSION_TMP_ROOT}/marked.XXXXXX")"
|
|
1281
2158
|
manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
|
|
1282
2159
|
if [[ -s "${local_source_file}" ]]; then
|
|
1283
|
-
mark_installed_packages "${manager}" "${local_source_file}" "${local_marked_file}"
|
|
1284
2160
|
awk -F'\t' -v mgr="${manager}" '
|
|
1285
2161
|
NF >= 1 {
|
|
1286
2162
|
desc = $2
|
|
1287
2163
|
if (desc == "") desc = "-"
|
|
1288
2164
|
print mgr "\t" $1 "\t" desc
|
|
1289
2165
|
}
|
|
1290
|
-
' "${
|
|
2166
|
+
' "${local_source_file}" >"${part_file}"
|
|
1291
2167
|
fi
|
|
1292
|
-
rm -f "${local_source_file}"
|
|
2168
|
+
rm -f "${local_source_file}"
|
|
1293
2169
|
) &
|
|
1294
2170
|
gather_pids+=("$!")
|
|
1295
2171
|
done
|
|
@@ -1298,15 +2174,19 @@ collect_search_display_rows() {
|
|
|
1298
2174
|
wait "${gather_pid}" || true
|
|
1299
2175
|
done
|
|
1300
2176
|
|
|
2177
|
+
merged_source_file="$(mktemp "${SESSION_TMP_ROOT}/merged-source.XXXXXX")"
|
|
2178
|
+
merged_marked_file="$(mktemp "${SESSION_TMP_ROOT}/merged-marked.XXXXXX")"
|
|
2179
|
+
|
|
1301
2180
|
for part_file in "${part_files[@]-}"; do
|
|
1302
2181
|
if [[ -s "${part_file}" ]]; then
|
|
1303
|
-
cat "${part_file}" >>"${
|
|
2182
|
+
cat "${part_file}" >>"${merged_source_file}"
|
|
1304
2183
|
fi
|
|
1305
2184
|
rm -f "${part_file}"
|
|
1306
2185
|
done
|
|
1307
2186
|
|
|
1308
|
-
if [[ -s "${
|
|
1309
|
-
|
|
2187
|
+
if [[ -s "${merged_source_file}" ]]; then
|
|
2188
|
+
merge_search_display_rows "${merged_source_file}" "${merged_marked_file}"
|
|
2189
|
+
mark_installed_packages "${merged_marked_file}" "${output_file}"
|
|
1310
2190
|
rank_display_rows_by_query "${query}" "${output_file}"
|
|
1311
2191
|
|
|
1312
2192
|
if [[ -n "${query}" && "${query_limit}" =~ ^[0-9]+$ && "${query_limit}" -gt 0 ]]; then
|
|
@@ -1314,6 +2194,8 @@ collect_search_display_rows() {
|
|
|
1314
2194
|
mv "${output_file}.limited" "${output_file}"
|
|
1315
2195
|
fi
|
|
1316
2196
|
fi
|
|
2197
|
+
|
|
2198
|
+
rm -f "${merged_source_file}" "${merged_marked_file}"
|
|
1317
2199
|
}
|
|
1318
2200
|
|
|
1319
2201
|
build_dynamic_reload_command() {
|
|
@@ -1336,10 +2218,195 @@ build_dynamic_reload_command() {
|
|
|
1336
2218
|
fi
|
|
1337
2219
|
|
|
1338
2220
|
if [[ -n "${manager_override}" ]]; then
|
|
1339
|
-
printf 'q={q}; if [ ${#q} -lt %s ]; then cat %q; else sleep %s; FPF_SKIP_INSTALLED_MARKERS=1 %q --feed-search --manager %q -- "$q" 2>/dev/null || cat %q; fi' "${min_chars}" "${fallback_file}" "${reload_debounce}" "${script_path}" "${manager_override}" "${fallback_file}"
|
|
2221
|
+
printf 'q={q}; if [ ${#q} -lt %s ]; then cat %q; else sleep %s; FPF_SKIP_INSTALLED_MARKERS=1 FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_FALLBACK_FILE=%q %q --feed-search --manager %q -- "$q" 2>/dev/null || cat %q; fi' "${min_chars}" "${fallback_file}" "${reload_debounce}" "${manager_override}" "${fallback_file}" "${script_path}" "${manager_override}" "${fallback_file}"
|
|
2222
|
+
else
|
|
2223
|
+
printf 'q={q}; if [ ${#q} -lt %s ]; then cat %q; else sleep %s; FPF_SKIP_INSTALLED_MARKERS=1 FPF_IPC_MANAGER_OVERRIDE= FPF_IPC_FALLBACK_FILE=%q %q --feed-search -- "$q" 2>/dev/null || cat %q; fi' "${min_chars}" "${fallback_file}" "${reload_debounce}" "${fallback_file}" "${script_path}" "${fallback_file}"
|
|
2224
|
+
fi
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
build_dynamic_reload_command_for_query() {
|
|
2228
|
+
local manager_override="$1"
|
|
2229
|
+
local fallback_file="$2"
|
|
2230
|
+
local query_value="$3"
|
|
2231
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
2232
|
+
local min_chars="${FPF_RELOAD_MIN_CHARS:-2}"
|
|
2233
|
+
local reload_debounce="${FPF_RELOAD_DEBOUNCE:-0.12}"
|
|
2234
|
+
|
|
2235
|
+
if ! [[ "${min_chars}" =~ ^[0-9]+$ ]]; then
|
|
2236
|
+
min_chars=2
|
|
2237
|
+
fi
|
|
2238
|
+
|
|
2239
|
+
if ! [[ "${reload_debounce}" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
2240
|
+
reload_debounce=0.12
|
|
2241
|
+
fi
|
|
2242
|
+
|
|
2243
|
+
if [[ "${script_path}" != /* ]]; then
|
|
2244
|
+
script_path="$(pwd)/${script_path}"
|
|
2245
|
+
fi
|
|
2246
|
+
|
|
2247
|
+
if [[ ${#query_value} -lt ${min_chars} ]]; then
|
|
2248
|
+
printf 'cat %q' "${fallback_file}"
|
|
2249
|
+
return
|
|
2250
|
+
fi
|
|
2251
|
+
|
|
2252
|
+
if [[ -n "${manager_override}" ]]; then
|
|
2253
|
+
printf 'sleep %s; FPF_SKIP_INSTALLED_MARKERS=1 FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_FALLBACK_FILE=%q %q --feed-search --manager %q -- %q 2>/dev/null || cat %q' "${reload_debounce}" "${manager_override}" "${fallback_file}" "${script_path}" "${manager_override}" "${query_value}" "${fallback_file}"
|
|
2254
|
+
else
|
|
2255
|
+
printf 'sleep %s; FPF_SKIP_INSTALLED_MARKERS=1 FPF_IPC_MANAGER_OVERRIDE= FPF_IPC_FALLBACK_FILE=%q %q --feed-search -- %q 2>/dev/null || cat %q' "${reload_debounce}" "${fallback_file}" "${script_path}" "${query_value}" "${fallback_file}"
|
|
2256
|
+
fi
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
build_dynamic_reload_ipc_command() {
|
|
2260
|
+
local manager_override="$1"
|
|
2261
|
+
local fallback_file="$2"
|
|
2262
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
2263
|
+
|
|
2264
|
+
if [[ "${script_path}" != /* ]]; then
|
|
2265
|
+
script_path="$(pwd)/${script_path}"
|
|
2266
|
+
fi
|
|
2267
|
+
|
|
2268
|
+
printf 'FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_FALLBACK_FILE=%q %q --ipc-reload -- "{q}"' "${manager_override}" "${fallback_file}" "${script_path}"
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
build_dynamic_query_notify_ipc_command() {
|
|
2272
|
+
local manager_override="$1"
|
|
2273
|
+
local fallback_file="$2"
|
|
2274
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
2275
|
+
|
|
2276
|
+
if [[ "${script_path}" != /* ]]; then
|
|
2277
|
+
script_path="$(pwd)/${script_path}"
|
|
2278
|
+
fi
|
|
2279
|
+
|
|
2280
|
+
printf 'FPF_IPC_MANAGER_OVERRIDE=%q FPF_IPC_FALLBACK_FILE=%q %q --ipc-query-notify -- "{q}"' "${manager_override}" "${fallback_file}" "${script_path}"
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
fzf_supports_listen() {
|
|
2284
|
+
local fzf_help
|
|
2285
|
+
fzf_help="$(fzf --help 2>&1 || true)"
|
|
2286
|
+
[[ "${fzf_help}" == *"--listen"* ]]
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
send_fzf_listen_action() {
|
|
2290
|
+
local action_payload="$1"
|
|
2291
|
+
local port="${FZF_PORT:-}"
|
|
2292
|
+
local host="127.0.0.1"
|
|
2293
|
+
local payload_size
|
|
2294
|
+
|
|
2295
|
+
if ! [[ "${port}" =~ ^[0-9]+$ ]] || [[ "${port}" -le 0 || "${port}" -gt 65535 ]]; then
|
|
2296
|
+
return 1
|
|
2297
|
+
fi
|
|
2298
|
+
|
|
2299
|
+
payload_size="$(printf "%s" "${action_payload}" | wc -c | tr -d '[:space:]')"
|
|
2300
|
+
|
|
2301
|
+
if command_exists curl; then
|
|
2302
|
+
curl --silent --show-error --fail --max-time 2 \
|
|
2303
|
+
--request POST \
|
|
2304
|
+
--header 'Content-Type: text/plain' \
|
|
2305
|
+
--data-binary "${action_payload}" \
|
|
2306
|
+
"http://${host}:${port}" >/dev/null 2>&1
|
|
2307
|
+
return
|
|
2308
|
+
fi
|
|
2309
|
+
|
|
2310
|
+
if command_exists nc; then
|
|
2311
|
+
{
|
|
2312
|
+
printf 'POST / HTTP/1.1\r\n'
|
|
2313
|
+
printf 'Host: %s:%s\r\n' "${host}" "${port}"
|
|
2314
|
+
printf 'Content-Type: text/plain\r\n'
|
|
2315
|
+
printf 'Content-Length: %s\r\n' "${payload_size}"
|
|
2316
|
+
printf '\r\n'
|
|
2317
|
+
printf '%s' "${action_payload}"
|
|
2318
|
+
} | nc -w 2 "${host}" "${port}" >/dev/null 2>&1
|
|
2319
|
+
return
|
|
2320
|
+
fi
|
|
2321
|
+
|
|
2322
|
+
if exec 9<>"/dev/tcp/${host}/${port}" 2>/dev/null; then
|
|
2323
|
+
printf 'POST / HTTP/1.1\r\n' >&9
|
|
2324
|
+
printf 'Host: %s:%s\r\n' "${host}" "${port}" >&9
|
|
2325
|
+
printf 'Content-Type: text/plain\r\n' >&9
|
|
2326
|
+
printf 'Content-Length: %s\r\n' "${payload_size}" >&9
|
|
2327
|
+
printf '\r\n' >&9
|
|
2328
|
+
printf '%s' "${action_payload}" >&9
|
|
2329
|
+
exec 9>&-
|
|
2330
|
+
return 0
|
|
2331
|
+
fi
|
|
2332
|
+
|
|
2333
|
+
return 1
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
send_fzf_prompt_action() {
|
|
2337
|
+
local prompt_text="$1"
|
|
2338
|
+
local action_payload
|
|
2339
|
+
|
|
2340
|
+
action_payload="change-prompt(${prompt_text})"
|
|
2341
|
+
send_fzf_listen_action "${action_payload}"
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
run_ipc_reload_action() {
|
|
2345
|
+
local query="$1"
|
|
2346
|
+
local manager_override="${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
2347
|
+
local fallback_file="${FPF_IPC_FALLBACK_FILE:-}"
|
|
2348
|
+
local reload_command
|
|
2349
|
+
local action_payload
|
|
2350
|
+
|
|
2351
|
+
if [[ -z "${fallback_file}" || ! -r "${fallback_file}" ]]; then
|
|
2352
|
+
return 1
|
|
2353
|
+
fi
|
|
2354
|
+
|
|
2355
|
+
if [[ -n "${manager_override}" ]]; then
|
|
2356
|
+
manager_override="$(normalize_manager "${manager_override}")"
|
|
2357
|
+
manager_supported "${manager_override}" || return 1
|
|
2358
|
+
fi
|
|
2359
|
+
|
|
2360
|
+
reload_command="$(build_dynamic_reload_command_for_query "${manager_override}" "${fallback_file}" "${query}")"
|
|
2361
|
+
action_payload="reload(${reload_command})+change-prompt(Search> )"
|
|
2362
|
+
send_fzf_listen_action "${action_payload}"
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
run_ipc_query_notify_action() {
|
|
2366
|
+
local query="$1"
|
|
2367
|
+
local manager_override="${FPF_IPC_MANAGER_OVERRIDE:-}"
|
|
2368
|
+
local fallback_file="${FPF_IPC_FALLBACK_FILE:-}"
|
|
2369
|
+
local min_chars="${FPF_RELOAD_MIN_CHARS:-2}"
|
|
2370
|
+
local target_manager=""
|
|
2371
|
+
|
|
2372
|
+
if ! [[ "${min_chars}" =~ ^[0-9]+$ ]]; then
|
|
2373
|
+
min_chars=2
|
|
2374
|
+
fi
|
|
2375
|
+
|
|
2376
|
+
if [[ ${#query} -lt ${min_chars} ]]; then
|
|
2377
|
+
send_fzf_prompt_action "Search> " || true
|
|
2378
|
+
return 0
|
|
2379
|
+
fi
|
|
2380
|
+
|
|
2381
|
+
if [[ -z "${fallback_file}" || ! -r "${fallback_file}" ]]; then
|
|
2382
|
+
return 1
|
|
2383
|
+
fi
|
|
2384
|
+
|
|
2385
|
+
if [[ -n "${manager_override}" ]]; then
|
|
2386
|
+
manager_override="$(normalize_manager "${manager_override}")"
|
|
2387
|
+
manager_supported "${manager_override}" || return 1
|
|
2388
|
+
target_manager="${manager_override}"
|
|
1340
2389
|
else
|
|
1341
|
-
|
|
2390
|
+
target_manager="bun"
|
|
2391
|
+
fi
|
|
2392
|
+
|
|
2393
|
+
if [[ "${target_manager}" != "bun" ]]; then
|
|
2394
|
+
send_fzf_prompt_action "Search> " || true
|
|
2395
|
+
return 0
|
|
2396
|
+
fi
|
|
2397
|
+
|
|
2398
|
+
if ! manager_command_ready bun; then
|
|
2399
|
+
send_fzf_prompt_action "Search> " || true
|
|
2400
|
+
return 0
|
|
1342
2401
|
fi
|
|
2402
|
+
|
|
2403
|
+
send_fzf_prompt_action "Loading> " || true
|
|
2404
|
+
|
|
2405
|
+
FPF_IPC_MANAGER_OVERRIDE="${manager_override}" \
|
|
2406
|
+
FPF_IPC_FALLBACK_FILE="${fallback_file}" \
|
|
2407
|
+
manager_search_entries "bun" "${query}" >/dev/null 2>&1 || {
|
|
2408
|
+
send_fzf_prompt_action "Search> " || true
|
|
2409
|
+
}
|
|
1343
2410
|
}
|
|
1344
2411
|
|
|
1345
2412
|
manager_install() {
|
|
@@ -1572,9 +2639,15 @@ run_fuzzy_selector() {
|
|
|
1572
2639
|
local input_file="$2"
|
|
1573
2640
|
local header_line="$3"
|
|
1574
2641
|
local reload_cmd="${4:-}"
|
|
2642
|
+
local reload_ipc_cmd="${5:-}"
|
|
2643
|
+
local script_path="${BASH_SOURCE[0]}"
|
|
1575
2644
|
local preview_cmd
|
|
1576
2645
|
|
|
1577
|
-
|
|
2646
|
+
if [[ "${script_path}" != /* ]]; then
|
|
2647
|
+
script_path="$(pwd)/${script_path}"
|
|
2648
|
+
fi
|
|
2649
|
+
|
|
2650
|
+
preview_cmd="FPF_SESSION_TMP_ROOT=$(printf '%q' "${SESSION_TMP_ROOT}") ${script_path} --preview-item --manager {1} -- {2}"
|
|
1578
2651
|
|
|
1579
2652
|
local -a fzf_args=()
|
|
1580
2653
|
fzf_args=(-q "${query}" -m \
|
|
@@ -1587,7 +2660,7 @@ run_fuzzy_selector() {
|
|
|
1587
2660
|
--marker='>>' \
|
|
1588
2661
|
--prompt='Search> ' \
|
|
1589
2662
|
--header="${header_line}" \
|
|
1590
|
-
--info=inline
|
|
2663
|
+
--info=inline \
|
|
1591
2664
|
--margin="2%,1%,2%,1%" \
|
|
1592
2665
|
--cycle \
|
|
1593
2666
|
--tiebreak=begin,chunk,length \
|
|
@@ -1597,8 +2670,14 @@ run_fuzzy_selector() {
|
|
|
1597
2670
|
--bind=ctrl-n:next-selected,ctrl-b:prev-selected \
|
|
1598
2671
|
--bind='focus:transform-preview-label:echo [{1}] {2}')
|
|
1599
2672
|
|
|
1600
|
-
if [[ -n "${
|
|
1601
|
-
fzf_args+=(--
|
|
2673
|
+
if [[ -n "${reload_ipc_cmd}" ]]; then
|
|
2674
|
+
fzf_args+=(--listen=127.0.0.1:0)
|
|
2675
|
+
fzf_args+=(--bind="change:execute-silent:${reload_ipc_cmd}")
|
|
2676
|
+
if [[ -n "${reload_cmd}" ]]; then
|
|
2677
|
+
fzf_args+=(--bind="ctrl-r:reload:${reload_cmd}")
|
|
2678
|
+
fi
|
|
2679
|
+
elif [[ -n "${reload_cmd}" ]]; then
|
|
2680
|
+
fzf_args+=(--bind="ctrl-r:reload:${reload_cmd}")
|
|
1602
2681
|
fi
|
|
1603
2682
|
|
|
1604
2683
|
fzf "${fzf_args[@]}" <"${input_file}"
|
|
@@ -1607,10 +2686,54 @@ run_fuzzy_selector() {
|
|
|
1607
2686
|
main() {
|
|
1608
2687
|
ensure_tmp_root
|
|
1609
2688
|
initialize_session_tmp_root
|
|
1610
|
-
|
|
2689
|
+
if [[ -z "${FPF_SESSION_TMP_ROOT:-}" ]]; then
|
|
2690
|
+
trap cleanup_session_tmp_root EXIT
|
|
2691
|
+
fi
|
|
1611
2692
|
|
|
1612
2693
|
parse_args "$@"
|
|
1613
2694
|
|
|
2695
|
+
if [[ "${ACTION}" == "ipc-reload" ]]; then
|
|
2696
|
+
run_ipc_reload_action "$(join_query)" || true
|
|
2697
|
+
exit 0
|
|
2698
|
+
fi
|
|
2699
|
+
|
|
2700
|
+
if [[ "${ACTION}" == "ipc-query-notify" ]]; then
|
|
2701
|
+
run_ipc_query_notify_action "$(join_query)" || true
|
|
2702
|
+
exit 0
|
|
2703
|
+
fi
|
|
2704
|
+
|
|
2705
|
+
if [[ "${ACTION}" == "preview-item" ]]; then
|
|
2706
|
+
local preview_manager="${MANAGER_OVERRIDE:-}"
|
|
2707
|
+
local preview_package
|
|
2708
|
+
|
|
2709
|
+
preview_package="$(join_query)"
|
|
2710
|
+
run_preview_item_action "${preview_manager}" "${preview_package}" || true
|
|
2711
|
+
exit 0
|
|
2712
|
+
fi
|
|
2713
|
+
|
|
2714
|
+
if [[ "${ACTION}" == "bun-refresh-worker" ]]; then
|
|
2715
|
+
local worker_manager="${MANAGER_OVERRIDE:-bun}"
|
|
2716
|
+
local worker_query
|
|
2717
|
+
local worker_flags
|
|
2718
|
+
local worker_key
|
|
2719
|
+
local worker_fingerprint
|
|
2720
|
+
local worker_generation
|
|
2721
|
+
|
|
2722
|
+
worker_query="$(join_query)"
|
|
2723
|
+
worker_flags="${FPF_BUN_REFRESH_FLAGS:-$(query_cache_flags)}"
|
|
2724
|
+
worker_key="${FPF_BUN_REFRESH_KEY:-$(cache_query_key "${worker_manager}" "${worker_query}" "${worker_flags}")}"
|
|
2725
|
+
worker_fingerprint="${FPF_BUN_REFRESH_FINGERPRINT:-$(cache_fingerprint "${worker_manager}" "${worker_query}" "${worker_flags}")}"
|
|
2726
|
+
worker_generation="${FPF_BUN_REFRESH_GENERATION:-0}"
|
|
2727
|
+
|
|
2728
|
+
if ! [[ "${worker_generation}" =~ ^[0-9]+$ ]] || [[ "${worker_generation}" -le 0 ]]; then
|
|
2729
|
+
exit 0
|
|
2730
|
+
fi
|
|
2731
|
+
|
|
2732
|
+
initialize_cache_root
|
|
2733
|
+
bun_run_refresh_worker "${worker_manager}" "${worker_query}" "${worker_flags}" "${worker_key}" "${worker_fingerprint}" "${worker_generation}" || true
|
|
2734
|
+
exit 0
|
|
2735
|
+
fi
|
|
2736
|
+
|
|
1614
2737
|
if [[ "${ACTION}" == "version" ]]; then
|
|
1615
2738
|
print_version
|
|
1616
2739
|
exit 0
|
|
@@ -1739,6 +2862,13 @@ main() {
|
|
|
1739
2862
|
|
|
1740
2863
|
if [[ ! -s "${display_file}" ]]; then
|
|
1741
2864
|
rm -f "${display_file}"
|
|
2865
|
+
|
|
2866
|
+
if [[ "${ACTION}" == "search" && "${#managers[@]}" -eq 1 && "${managers[0]}" == "flatpak" ]]; then
|
|
2867
|
+
if ! flatpak_has_any_remotes; then
|
|
2868
|
+
die "Flatpak has no remotes configured. Add Flathub with: flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo"
|
|
2869
|
+
fi
|
|
2870
|
+
fi
|
|
2871
|
+
|
|
1742
2872
|
if [[ -n "${query}" ]]; then
|
|
1743
2873
|
die "No packages found for ${manager_display} matching '${query}'. Try a broader query or --manager."
|
|
1744
2874
|
fi
|
|
@@ -1762,14 +2892,18 @@ main() {
|
|
|
1762
2892
|
esac
|
|
1763
2893
|
|
|
1764
2894
|
local reload_cmd=""
|
|
2895
|
+
local reload_ipc_cmd=""
|
|
1765
2896
|
if [[ "${ACTION}" == "search" && -z "${query}" ]]; then
|
|
1766
2897
|
if dynamic_reload_enabled "${#managers[@]}"; then
|
|
1767
2898
|
reload_cmd="$(build_dynamic_reload_command "${MANAGER_OVERRIDE}" "${display_file}")"
|
|
2899
|
+
if fzf_supports_listen; then
|
|
2900
|
+
reload_ipc_cmd="$(build_dynamic_query_notify_ipc_command "${MANAGER_OVERRIDE}" "${display_file}")"
|
|
2901
|
+
fi
|
|
1768
2902
|
fi
|
|
1769
2903
|
fi
|
|
1770
2904
|
|
|
1771
2905
|
local selected
|
|
1772
|
-
selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" "${reload_cmd}" || true)"
|
|
2906
|
+
selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" "${reload_cmd}" "${reload_ipc_cmd}" || true)"
|
|
1773
2907
|
|
|
1774
2908
|
rm -f "${display_file}"
|
|
1775
2909
|
|
|
@@ -1824,7 +2958,7 @@ main() {
|
|
|
1824
2958
|
if confirm_action "Install ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
1825
2959
|
for manager in "${unique_managers[@]-}"; do
|
|
1826
2960
|
mgr_packages=()
|
|
1827
|
-
for idx in "${!selected_packages[@]
|
|
2961
|
+
for idx in "${!selected_packages[@]}"; do
|
|
1828
2962
|
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
1829
2963
|
mgr_packages+=("${selected_packages[$idx]}")
|
|
1830
2964
|
fi
|
|
@@ -1842,7 +2976,7 @@ main() {
|
|
|
1842
2976
|
if confirm_action "Remove ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
1843
2977
|
for manager in "${unique_managers[@]-}"; do
|
|
1844
2978
|
mgr_packages=()
|
|
1845
|
-
for idx in "${!selected_packages[@]
|
|
2979
|
+
for idx in "${!selected_packages[@]}"; do
|
|
1846
2980
|
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
1847
2981
|
mgr_packages+=("${selected_packages[$idx]}")
|
|
1848
2982
|
fi
|
|
@@ -1857,7 +2991,7 @@ main() {
|
|
|
1857
2991
|
fi
|
|
1858
2992
|
;;
|
|
1859
2993
|
list)
|
|
1860
|
-
for idx in "${!selected_packages[@]
|
|
2994
|
+
for idx in "${!selected_packages[@]}"; do
|
|
1861
2995
|
printf "\n=== %s (%s) ===\n" "${selected_packages[$idx]}" "$(manager_label "${selected_managers[$idx]}")"
|
|
1862
2996
|
manager_show_info "${selected_managers[$idx]}" "${selected_packages[$idx]}" || true
|
|
1863
2997
|
done
|