fpf-cli 1.6.35 → 1.6.37
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 +206 -8
- 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 DynamicProgress-style pre-search bar with concurrent per-manager task text + 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.37"
|
|
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,154 @@ 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_repeat_char() {
|
|
102
|
+
local count="$1"
|
|
103
|
+
local char="$2"
|
|
104
|
+
local chunk=""
|
|
105
|
+
|
|
106
|
+
if ! [[ "${count}" =~ ^[0-9]+$ ]] || [[ "${count}" -le 0 ]]; then
|
|
107
|
+
return 0
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
printf -v chunk "%*s" "${count}" ""
|
|
111
|
+
printf "%s" "${chunk// /${char}}"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
loading_progress_snapshot() {
|
|
115
|
+
local status_file=""
|
|
116
|
+
local manager=""
|
|
117
|
+
local status=""
|
|
118
|
+
local detail=""
|
|
119
|
+
local bar_width="${FPF_LOADING_BAR_WIDTH:-26}"
|
|
120
|
+
local total=0
|
|
121
|
+
local done=0
|
|
122
|
+
local running=0
|
|
123
|
+
local queued=0
|
|
124
|
+
local progress_percent=0
|
|
125
|
+
local filled_width=0
|
|
126
|
+
local remaining_width=0
|
|
127
|
+
local bar=""
|
|
128
|
+
local -a active_details=()
|
|
129
|
+
local active_text=""
|
|
130
|
+
local phase_text=""
|
|
131
|
+
local idx
|
|
132
|
+
|
|
133
|
+
if [[ -z "${LOADING_PROGRESS_DIR}" || ! -d "${LOADING_PROGRESS_DIR}" ]]; then
|
|
134
|
+
return 0
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
if ! [[ "${bar_width}" =~ ^[0-9]+$ ]] || [[ "${bar_width}" -lt 10 ]]; then
|
|
138
|
+
bar_width=26
|
|
139
|
+
fi
|
|
140
|
+
if [[ "${bar_width}" -gt 60 ]]; then
|
|
141
|
+
bar_width=60
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
for status_file in "${LOADING_PROGRESS_DIR}"/*.status; do
|
|
145
|
+
[[ -f "${status_file}" ]] || continue
|
|
146
|
+
total=$((total + 1))
|
|
147
|
+
manager="$(basename "${status_file}" .status)"
|
|
148
|
+
IFS=$'\t' read -r status detail <"${status_file}" || true
|
|
149
|
+
case "${status}" in
|
|
150
|
+
done)
|
|
151
|
+
done=$((done + 1))
|
|
152
|
+
;;
|
|
153
|
+
running)
|
|
154
|
+
running=$((running + 1))
|
|
155
|
+
active_details+=("$(manager_label "${manager}"): ${detail:-working}")
|
|
156
|
+
;;
|
|
157
|
+
*)
|
|
158
|
+
queued=$((queued + 1))
|
|
159
|
+
;;
|
|
160
|
+
esac
|
|
161
|
+
done
|
|
162
|
+
|
|
163
|
+
[[ "${total}" -gt 0 ]] || return 0
|
|
164
|
+
|
|
165
|
+
progress_percent=$((done * 100 / total))
|
|
166
|
+
filled_width=$((done * bar_width / total))
|
|
167
|
+
if [[ "${done}" -ge "${total}" ]]; then
|
|
168
|
+
bar="$(loading_progress_repeat_char "${bar_width}" "=")"
|
|
169
|
+
else
|
|
170
|
+
remaining_width=$((bar_width - filled_width - 1))
|
|
171
|
+
bar="$(loading_progress_repeat_char "${filled_width}" "=")>"
|
|
172
|
+
if [[ "${remaining_width}" -gt 0 ]]; then
|
|
173
|
+
bar+=$(printf "%${remaining_width}s" "")
|
|
174
|
+
fi
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
if [[ "${#active_details[@]}" -gt 0 ]]; then
|
|
178
|
+
active_text=""
|
|
179
|
+
for idx in "${!active_details[@]}"; do
|
|
180
|
+
if [[ -n "${active_text}" ]]; then
|
|
181
|
+
active_text+="; "
|
|
182
|
+
fi
|
|
183
|
+
active_text+="${active_details[$idx]}"
|
|
184
|
+
done
|
|
185
|
+
phase_text="active: ${active_text}"
|
|
186
|
+
elif [[ "${queued}" -gt 0 ]]; then
|
|
187
|
+
phase_text="starting queued managers (${queued} remaining)"
|
|
188
|
+
else
|
|
189
|
+
phase_text="finalizing combined results"
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
printf "[%s] %3s%% (%s/%s) | %s" "${bar}" "${progress_percent}" "${done}" "${total}" "${phase_text}"
|
|
193
|
+
}
|
|
194
|
+
|
|
46
195
|
start_loading_indicator() {
|
|
47
196
|
local message="${1:-Loading}"
|
|
48
197
|
|
|
@@ -54,11 +203,27 @@ start_loading_indicator() {
|
|
|
54
203
|
|
|
55
204
|
(
|
|
56
205
|
trap 'exit 0' TERM INT
|
|
57
|
-
local
|
|
58
|
-
local
|
|
206
|
+
local started_epoch
|
|
207
|
+
local elapsed_seconds=0
|
|
208
|
+
local snapshot=""
|
|
209
|
+
|
|
210
|
+
started_epoch="$(date +%s)"
|
|
211
|
+
if ! [[ "${started_epoch}" =~ ^[0-9]+$ ]]; then
|
|
212
|
+
started_epoch=0
|
|
213
|
+
fi
|
|
214
|
+
|
|
59
215
|
while true; do
|
|
60
|
-
|
|
61
|
-
|
|
216
|
+
elapsed_seconds="$(( $(date +%s) - started_epoch ))"
|
|
217
|
+
if [[ "${elapsed_seconds}" -lt 0 ]]; then
|
|
218
|
+
elapsed_seconds=0
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
snapshot="$(loading_progress_snapshot)"
|
|
222
|
+
if [[ -n "${snapshot}" ]]; then
|
|
223
|
+
printf "\r\033[2K%s %s | elapsed: %ss" "${message}" "${snapshot}" "${elapsed_seconds}" >&2
|
|
224
|
+
else
|
|
225
|
+
printf "\r\033[2K%s [working] | elapsed: %ss" "${message}" "${elapsed_seconds}" >&2
|
|
226
|
+
fi
|
|
62
227
|
sleep 0.1
|
|
63
228
|
done
|
|
64
229
|
) &
|
|
@@ -929,6 +1094,7 @@ run_preview_item_action() {
|
|
|
929
1094
|
|
|
930
1095
|
cleanup_session_tmp_root() {
|
|
931
1096
|
stop_loading_indicator
|
|
1097
|
+
loading_progress_end
|
|
932
1098
|
|
|
933
1099
|
if [[ -n "${SESSION_TMP_ROOT}" && -d "${SESSION_TMP_ROOT}" ]]; then
|
|
934
1100
|
rm -rf "${SESSION_TMP_ROOT}"
|
|
@@ -2780,6 +2946,10 @@ collect_search_display_rows() {
|
|
|
2780
2946
|
part_files+=("${part_file}")
|
|
2781
2947
|
|
|
2782
2948
|
(
|
|
2949
|
+
local local_source_file
|
|
2950
|
+
local result_count=0
|
|
2951
|
+
|
|
2952
|
+
loading_progress_mark_running "${manager}" "querying package index"
|
|
2783
2953
|
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
2784
2954
|
manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
|
|
2785
2955
|
if [[ -s "${local_source_file}" ]]; then
|
|
@@ -2792,6 +2962,11 @@ collect_search_display_rows() {
|
|
|
2792
2962
|
' "${local_source_file}" >"${part_file}"
|
|
2793
2963
|
fi
|
|
2794
2964
|
rm -f "${local_source_file}"
|
|
2965
|
+
|
|
2966
|
+
if [[ -s "${part_file}" ]]; then
|
|
2967
|
+
result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
|
|
2968
|
+
fi
|
|
2969
|
+
loading_progress_mark_done "${manager}" "${result_count} packages matched"
|
|
2795
2970
|
) &
|
|
2796
2971
|
gather_pids+=("$!")
|
|
2797
2972
|
done
|
|
@@ -2842,6 +3017,9 @@ collect_installed_display_rows() {
|
|
|
2842
3017
|
|
|
2843
3018
|
(
|
|
2844
3019
|
local local_source_file
|
|
3020
|
+
local result_count=0
|
|
3021
|
+
|
|
3022
|
+
loading_progress_mark_running "${manager}" "reading installed package list"
|
|
2845
3023
|
local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
|
|
2846
3024
|
manager_installed_entries "${manager}" >"${local_source_file}" || true
|
|
2847
3025
|
if [[ -s "${local_source_file}" ]]; then
|
|
@@ -2854,6 +3032,11 @@ collect_installed_display_rows() {
|
|
|
2854
3032
|
' "${local_source_file}" >"${part_file}"
|
|
2855
3033
|
fi
|
|
2856
3034
|
rm -f "${local_source_file}"
|
|
3035
|
+
|
|
3036
|
+
if [[ -s "${part_file}" ]]; then
|
|
3037
|
+
result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
|
|
3038
|
+
fi
|
|
3039
|
+
loading_progress_mark_done "${manager}" "${result_count} installed packages"
|
|
2857
3040
|
) &
|
|
2858
3041
|
gather_pids+=("$!")
|
|
2859
3042
|
done
|
|
@@ -3405,9 +3588,19 @@ main() {
|
|
|
3405
3588
|
ensure_fzf "${managers[@]-}"
|
|
3406
3589
|
|
|
3407
3590
|
if [[ "${ACTION}" == "search" ]]; then
|
|
3408
|
-
|
|
3591
|
+
loading_progress_begin "${managers[@]-}"
|
|
3592
|
+
if ! run_with_loading_indicator "Loading packages from ${manager_display}" collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"; then
|
|
3593
|
+
loading_progress_end
|
|
3594
|
+
die "Failed to load package search results."
|
|
3595
|
+
fi
|
|
3596
|
+
loading_progress_end
|
|
3409
3597
|
else
|
|
3410
|
-
|
|
3598
|
+
loading_progress_begin "${managers[@]-}"
|
|
3599
|
+
if ! run_with_loading_indicator "Loading installed packages from ${manager_display}" collect_installed_display_rows "${display_file}" "${managers[@]-}"; then
|
|
3600
|
+
loading_progress_end
|
|
3601
|
+
die "Failed to load installed package results."
|
|
3602
|
+
fi
|
|
3603
|
+
loading_progress_end
|
|
3411
3604
|
fi
|
|
3412
3605
|
|
|
3413
3606
|
if [[ ! -s "${display_file}" ]]; then
|
|
@@ -3450,7 +3643,12 @@ main() {
|
|
|
3450
3643
|
if dynamic_reload_enabled "${#managers[@]}"; then
|
|
3451
3644
|
if [[ -n "${query}" ]]; then
|
|
3452
3645
|
reload_fallback_file="$(mktemp "${SESSION_TMP_ROOT}/reload-fallback.XXXXXX")"
|
|
3453
|
-
|
|
3646
|
+
loading_progress_begin "${managers[@]-}"
|
|
3647
|
+
if ! run_with_loading_indicator "Preparing baseline search results" collect_search_display_rows "" "${reload_fallback_file}" "${managers[@]-}"; then
|
|
3648
|
+
loading_progress_end
|
|
3649
|
+
die "Failed to prepare baseline search results."
|
|
3650
|
+
fi
|
|
3651
|
+
loading_progress_end
|
|
3454
3652
|
if [[ ! -s "${reload_fallback_file}" ]]; then
|
|
3455
3653
|
cp "${display_file}" "${reload_fallback_file}"
|
|
3456
3654
|
fi
|