fpf-cli 1.6.35 → 1.6.36
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 +2 -1
- package/fpf +175 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -98,7 +98,8 @@ Installed packages are marked with `*` in the result list.
|
|
|
98
98
|
- `FPF_DYNAMIC_RELOAD`: `always` (default), `single`, or `never`
|
|
99
99
|
- Live reload uses `change:reload` by default for reliability (`ctrl-r` uses the same reload command).
|
|
100
100
|
- Set `FPF_DYNAMIC_RELOAD_TRANSPORT=ipc` to opt into `--listen` + IPC query notifications on supported `fzf` builds.
|
|
101
|
-
-
|
|
101
|
+
- Startup now shows a dynamic pre-search loader with per-manager progress + elapsed time.
|
|
102
|
+
- Set `FPF_LOADING_INDICATOR=0` to disable the pre-search loading indicator.
|
|
102
103
|
- `FPF_RELOAD_MIN_CHARS`: minimum query length before live reload (default `2`)
|
|
103
104
|
- `FPF_RELOAD_DEBOUNCE`: reload debounce seconds (default `0.12`)
|
|
104
105
|
- `FPF_DISABLE_INSTALLED_CACHE=1` disables installed-package marker cache
|
package/fpf
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
5
|
SCRIPT_NAME="fpf"
|
|
6
|
-
SCRIPT_VERSION="1.6.
|
|
6
|
+
SCRIPT_VERSION="1.6.36"
|
|
7
7
|
TMP_ROOT="${TMPDIR:-/tmp}/fpf"
|
|
8
8
|
SESSION_TMP_ROOT=""
|
|
9
9
|
HELP_FILE=""
|
|
@@ -11,6 +11,7 @@ KBINDS_FILE=""
|
|
|
11
11
|
CACHE_FORMAT_VERSION="1"
|
|
12
12
|
CACHE_ROOT=""
|
|
13
13
|
LOADING_INDICATOR_PID=""
|
|
14
|
+
LOADING_PROGRESS_DIR=""
|
|
14
15
|
|
|
15
16
|
ACTION="search"
|
|
16
17
|
MANAGER_OVERRIDE=""
|
|
@@ -43,6 +44,123 @@ loading_indicator_enabled() {
|
|
|
43
44
|
[[ -t 2 ]]
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
loading_progress_begin() {
|
|
48
|
+
local managers=("$@")
|
|
49
|
+
local manager=""
|
|
50
|
+
local progress_file=""
|
|
51
|
+
|
|
52
|
+
loading_progress_end
|
|
53
|
+
loading_indicator_enabled || return 0
|
|
54
|
+
[[ "${#managers[@]}" -gt 0 ]] || return 0
|
|
55
|
+
|
|
56
|
+
LOADING_PROGRESS_DIR="$(mktemp -d "${SESSION_TMP_ROOT}/loading-progress.XXXXXX")"
|
|
57
|
+
for manager in "${managers[@]-}"; do
|
|
58
|
+
progress_file="${LOADING_PROGRESS_DIR}/${manager}.status"
|
|
59
|
+
printf "pending\tqueued\n" >"${progress_file}"
|
|
60
|
+
done
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
loading_progress_end() {
|
|
64
|
+
if [[ -z "${LOADING_PROGRESS_DIR}" ]]; then
|
|
65
|
+
return 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [[ -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
69
|
+
rm -rf "${LOADING_PROGRESS_DIR}" >/dev/null 2>&1 || true
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
LOADING_PROGRESS_DIR=""
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
loading_progress_mark_state() {
|
|
76
|
+
local manager="$1"
|
|
77
|
+
local state="$2"
|
|
78
|
+
local detail="${3:-}"
|
|
79
|
+
local progress_file=""
|
|
80
|
+
|
|
81
|
+
if [[ -z "${LOADING_PROGRESS_DIR}" || ! -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
82
|
+
return 0
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
progress_file="${LOADING_PROGRESS_DIR}/${manager}.status"
|
|
86
|
+
printf "%s\t%s\n" "${state}" "${detail}" >"${progress_file}" 2>/dev/null || true
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
loading_progress_mark_running() {
|
|
90
|
+
local manager="$1"
|
|
91
|
+
local detail="${2:-working}"
|
|
92
|
+
loading_progress_mark_state "${manager}" "running" "${detail}"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
loading_progress_mark_done() {
|
|
96
|
+
local manager="$1"
|
|
97
|
+
local detail="${2:-done}"
|
|
98
|
+
loading_progress_mark_state "${manager}" "done" "${detail}"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
loading_progress_snapshot() {
|
|
102
|
+
local status_file=""
|
|
103
|
+
local manager=""
|
|
104
|
+
local status=""
|
|
105
|
+
local detail=""
|
|
106
|
+
local total=0
|
|
107
|
+
local done=0
|
|
108
|
+
local running=0
|
|
109
|
+
local queued=0
|
|
110
|
+
local -a active_details=()
|
|
111
|
+
local active_display=""
|
|
112
|
+
local idx
|
|
113
|
+
|
|
114
|
+
if [[ -z "${LOADING_PROGRESS_DIR}" || ! -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
115
|
+
return 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
for status_file in "${LOADING_PROGRESS_DIR}"/*.status; do
|
|
119
|
+
[[ -f "${status_file}" ]] || continue
|
|
120
|
+
total=$((total + 1))
|
|
121
|
+
manager="$(basename "${status_file}" .status)"
|
|
122
|
+
IFS=$'\t' read -r status detail <"${status_file}" || true
|
|
123
|
+
case "${status}" in
|
|
124
|
+
done)
|
|
125
|
+
done=$((done + 1))
|
|
126
|
+
;;
|
|
127
|
+
running)
|
|
128
|
+
running=$((running + 1))
|
|
129
|
+
if [[ "${#active_details[@]}" -lt 2 ]]; then
|
|
130
|
+
active_details+=("$(manager_label "${manager}"): ${detail:-working}")
|
|
131
|
+
fi
|
|
132
|
+
;;
|
|
133
|
+
*)
|
|
134
|
+
queued=$((queued + 1))
|
|
135
|
+
;;
|
|
136
|
+
esac
|
|
137
|
+
done
|
|
138
|
+
|
|
139
|
+
[[ "${total}" -gt 0 ]] || return 0
|
|
140
|
+
|
|
141
|
+
active_display=""
|
|
142
|
+
for idx in "${!active_details[@]}"; do
|
|
143
|
+
if [[ -n "${active_display}" ]]; then
|
|
144
|
+
active_display+=", "
|
|
145
|
+
fi
|
|
146
|
+
active_display+="${active_details[$idx]}"
|
|
147
|
+
done
|
|
148
|
+
if [[ "${running}" -gt "${#active_details[@]}" ]]; then
|
|
149
|
+
if [[ -n "${active_display}" ]]; then
|
|
150
|
+
active_display+=", "
|
|
151
|
+
fi
|
|
152
|
+
active_display+="+$((running - ${#active_details[@]})) more"
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
printf "%s/%s done" "${done}" "${total}"
|
|
156
|
+
if [[ -n "${active_display}" ]]; then
|
|
157
|
+
printf " | active: %s" "${active_display}"
|
|
158
|
+
fi
|
|
159
|
+
if [[ "${queued}" -gt 0 ]]; then
|
|
160
|
+
printf " | queued: %s" "${queued}"
|
|
161
|
+
fi
|
|
162
|
+
}
|
|
163
|
+
|
|
46
164
|
start_loading_indicator() {
|
|
47
165
|
local message="${1:-Loading}"
|
|
48
166
|
|
|
@@ -56,8 +174,27 @@ start_loading_indicator() {
|
|
|
56
174
|
trap 'exit 0' TERM INT
|
|
57
175
|
local frames='|/-\'
|
|
58
176
|
local frame_index=0
|
|
177
|
+
local started_epoch
|
|
178
|
+
local elapsed_seconds=0
|
|
179
|
+
local snapshot=""
|
|
180
|
+
|
|
181
|
+
started_epoch="$(date +%s)"
|
|
182
|
+
if ! [[ "${started_epoch}" =~ ^[0-9]+$ ]]; then
|
|
183
|
+
started_epoch=0
|
|
184
|
+
fi
|
|
185
|
+
|
|
59
186
|
while true; do
|
|
60
|
-
|
|
187
|
+
elapsed_seconds="$(( $(date +%s) - started_epoch ))"
|
|
188
|
+
if [[ "${elapsed_seconds}" -lt 0 ]]; then
|
|
189
|
+
elapsed_seconds=0
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
snapshot="$(loading_progress_snapshot)"
|
|
193
|
+
if [[ -n "${snapshot}" ]]; then
|
|
194
|
+
printf "\r\033[2K%s [%s] %s | elapsed: %ss" "${message}" "${frames:frame_index:1}" "${snapshot}" "${elapsed_seconds}" >&2
|
|
195
|
+
else
|
|
196
|
+
printf "\r\033[2K%s [%s] elapsed: %ss" "${message}" "${frames:frame_index:1}" "${elapsed_seconds}" >&2
|
|
197
|
+
fi
|
|
61
198
|
frame_index=$(((frame_index + 1) % 4))
|
|
62
199
|
sleep 0.1
|
|
63
200
|
done
|
|
@@ -929,6 +1066,7 @@ run_preview_item_action() {
|
|
|
929
1066
|
|
|
930
1067
|
cleanup_session_tmp_root() {
|
|
931
1068
|
stop_loading_indicator
|
|
1069
|
+
loading_progress_end
|
|
932
1070
|
|
|
933
1071
|
if [[ -n "${SESSION_TMP_ROOT}" && -d "${SESSION_TMP_ROOT}" ]]; then
|
|
934
1072
|
rm -rf "${SESSION_TMP_ROOT}"
|
|
@@ -2780,6 +2918,10 @@ collect_search_display_rows() {
|
|
|
2780
2918
|
part_files+=("${part_file}")
|
|
2781
2919
|
|
|
2782
2920
|
(
|
|
2921
|
+
local local_source_file
|
|
2922
|
+
local result_count=0
|
|
2923
|
+
|
|
2924
|
+
loading_progress_mark_running "${manager}" "searching package index"
|
|
2783
2925
|
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
2784
2926
|
manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
|
|
2785
2927
|
if [[ -s "${local_source_file}" ]]; then
|
|
@@ -2792,6 +2934,11 @@ collect_search_display_rows() {
|
|
|
2792
2934
|
' "${local_source_file}" >"${part_file}"
|
|
2793
2935
|
fi
|
|
2794
2936
|
rm -f "${local_source_file}"
|
|
2937
|
+
|
|
2938
|
+
if [[ -s "${part_file}" ]]; then
|
|
2939
|
+
result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
|
|
2940
|
+
fi
|
|
2941
|
+
loading_progress_mark_done "${manager}" "${result_count} results indexed"
|
|
2795
2942
|
) &
|
|
2796
2943
|
gather_pids+=("$!")
|
|
2797
2944
|
done
|
|
@@ -2842,6 +2989,9 @@ collect_installed_display_rows() {
|
|
|
2842
2989
|
|
|
2843
2990
|
(
|
|
2844
2991
|
local local_source_file
|
|
2992
|
+
local result_count=0
|
|
2993
|
+
|
|
2994
|
+
loading_progress_mark_running "${manager}" "reading installed packages"
|
|
2845
2995
|
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
2846
2996
|
manager_installed_entries "${manager}" >"${local_source_file}" || true
|
|
2847
2997
|
if [[ -s "${local_source_file}" ]]; then
|
|
@@ -2854,6 +3004,11 @@ collect_installed_display_rows() {
|
|
|
2854
3004
|
' "${local_source_file}" >"${part_file}"
|
|
2855
3005
|
fi
|
|
2856
3006
|
rm -f "${local_source_file}"
|
|
3007
|
+
|
|
3008
|
+
if [[ -s "${part_file}" ]]; then
|
|
3009
|
+
result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
|
|
3010
|
+
fi
|
|
3011
|
+
loading_progress_mark_done "${manager}" "${result_count} installed entries"
|
|
2857
3012
|
) &
|
|
2858
3013
|
gather_pids+=("$!")
|
|
2859
3014
|
done
|
|
@@ -3405,9 +3560,19 @@ main() {
|
|
|
3405
3560
|
ensure_fzf "${managers[@]-}"
|
|
3406
3561
|
|
|
3407
3562
|
if [[ "${ACTION}" == "search" ]]; then
|
|
3408
|
-
|
|
3563
|
+
loading_progress_begin "${managers[@]-}"
|
|
3564
|
+
if ! run_with_loading_indicator "Loading packages from ${manager_display}" collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"; then
|
|
3565
|
+
loading_progress_end
|
|
3566
|
+
die "Failed to load package search results."
|
|
3567
|
+
fi
|
|
3568
|
+
loading_progress_end
|
|
3409
3569
|
else
|
|
3410
|
-
|
|
3570
|
+
loading_progress_begin "${managers[@]-}"
|
|
3571
|
+
if ! run_with_loading_indicator "Loading installed packages from ${manager_display}" collect_installed_display_rows "${display_file}" "${managers[@]-}"; then
|
|
3572
|
+
loading_progress_end
|
|
3573
|
+
die "Failed to load installed package results."
|
|
3574
|
+
fi
|
|
3575
|
+
loading_progress_end
|
|
3411
3576
|
fi
|
|
3412
3577
|
|
|
3413
3578
|
if [[ ! -s "${display_file}" ]]; then
|
|
@@ -3450,7 +3615,12 @@ main() {
|
|
|
3450
3615
|
if dynamic_reload_enabled "${#managers[@]}"; then
|
|
3451
3616
|
if [[ -n "${query}" ]]; then
|
|
3452
3617
|
reload_fallback_file="$(mktemp "${SESSION_TMP_ROOT}/reload-fallback.XXXXXX")"
|
|
3453
|
-
|
|
3618
|
+
loading_progress_begin "${managers[@]-}"
|
|
3619
|
+
if ! run_with_loading_indicator "Preparing baseline search results" collect_search_display_rows "" "${reload_fallback_file}" "${managers[@]-}"; then
|
|
3620
|
+
loading_progress_end
|
|
3621
|
+
die "Failed to prepare baseline search results."
|
|
3622
|
+
fi
|
|
3623
|
+
loading_progress_end
|
|
3454
3624
|
if [[ ! -s "${reload_fallback_file}" ]]; then
|
|
3455
3625
|
cp "${display_file}" "${reload_fallback_file}"
|
|
3456
3626
|
fi
|