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.
Files changed (3) hide show
  1. package/README.md +2 -1
  2. package/fpf +175 -5
  3. 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
- - Set `FPF_LOADING_INDICATOR=0` to disable the pre-search loading spinner.
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.35"
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
- printf "\r\033[2K%s [%s]" "${message}" "${frames:frame_index:1}" >&2
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
- run_with_loading_indicator "Loading packages from ${manager_display}" collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"
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
- run_with_loading_indicator "Loading installed packages from ${manager_display}" collect_installed_display_rows "${display_file}" "${managers[@]-}"
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
- run_with_loading_indicator "Preparing baseline search results" collect_search_display_rows "" "${reload_fallback_file}" "${managers[@]-}"
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fpf-cli",
3
- "version": "1.6.35",
3
+ "version": "1.6.36",
4
4
  "description": "Cross-platform fuzzy package finder powered by fzf",
5
5
  "bin": {
6
6
  "fpf": "fpf"