fpf-cli 1.6.36 → 1.6.38

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 +1 -1
  2. package/fpf +115 -37
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -98,7 +98,7 @@ 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
- - Startup now shows a dynamic pre-search loader with per-manager progress + elapsed time.
101
+ - Startup now shows a DynamicProgress-style pre-search bar with concurrent per-manager task text + elapsed time.
102
102
  - Set `FPF_LOADING_INDICATOR=0` to disable the pre-search loading indicator.
103
103
  - `FPF_RELOAD_MIN_CHARS`: minimum query length before live reload (default `2`)
104
104
  - `FPF_RELOAD_DEBOUNCE`: reload debounce seconds (default `0.12`)
package/fpf CHANGED
@@ -3,7 +3,7 @@
3
3
  set -euo pipefail
4
4
 
5
5
  SCRIPT_NAME="fpf"
6
- SCRIPT_VERSION="1.6.36"
6
+ SCRIPT_VERSION="1.6.38"
7
7
  TMP_ROOT="${TMPDIR:-/tmp}/fpf"
8
8
  SESSION_TMP_ROOT=""
9
9
  HELP_FILE=""
@@ -98,23 +98,49 @@ loading_progress_mark_done() {
98
98
  loading_progress_mark_state "${manager}" "done" "${detail}"
99
99
  }
100
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
+
101
114
  loading_progress_snapshot() {
102
115
  local status_file=""
103
116
  local manager=""
104
117
  local status=""
105
118
  local detail=""
119
+ local bar_width="${FPF_LOADING_BAR_WIDTH:-26}"
106
120
  local total=0
107
121
  local done=0
108
122
  local running=0
109
123
  local queued=0
124
+ local progress_percent=0
125
+ local filled_width=0
126
+ local remaining_width=0
127
+ local bar=""
110
128
  local -a active_details=()
111
- local active_display=""
129
+ local active_text=""
130
+ local phase_text=""
112
131
  local idx
113
132
 
114
133
  if [[ -z "${LOADING_PROGRESS_DIR}" || ! -d "${LOADING_PROGRESS_DIR}" ]]; then
115
134
  return 0
116
135
  fi
117
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
+
118
144
  for status_file in "${LOADING_PROGRESS_DIR}"/*.status; do
119
145
  [[ -f "${status_file}" ]] || continue
120
146
  total=$((total + 1))
@@ -126,9 +152,7 @@ loading_progress_snapshot() {
126
152
  ;;
127
153
  running)
128
154
  running=$((running + 1))
129
- if [[ "${#active_details[@]}" -lt 2 ]]; then
130
- active_details+=("$(manager_label "${manager}"): ${detail:-working}")
131
- fi
155
+ active_details+=("$(manager_label "${manager}"): ${detail:-working}")
132
156
  ;;
133
157
  *)
134
158
  queued=$((queued + 1))
@@ -138,27 +162,34 @@ loading_progress_snapshot() {
138
162
 
139
163
  [[ "${total}" -gt 0 ]] || return 0
140
164
 
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+=", "
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" "")
151
174
  fi
152
- active_display+="+$((running - ${#active_details[@]})) more"
153
175
  fi
154
176
 
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}"
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"
161
190
  fi
191
+
192
+ printf "[%s] %3s%% (%s/%s) | %s" "${bar}" "${progress_percent}" "${done}" "${total}" "${phase_text}"
162
193
  }
163
194
 
164
195
  start_loading_indicator() {
@@ -172,8 +203,6 @@ start_loading_indicator() {
172
203
 
173
204
  (
174
205
  trap 'exit 0' TERM INT
175
- local frames='|/-\'
176
- local frame_index=0
177
206
  local started_epoch
178
207
  local elapsed_seconds=0
179
208
  local snapshot=""
@@ -191,11 +220,10 @@ start_loading_indicator() {
191
220
 
192
221
  snapshot="$(loading_progress_snapshot)"
193
222
  if [[ -n "${snapshot}" ]]; then
194
- printf "\r\033[2K%s [%s] %s | elapsed: %ss" "${message}" "${frames:frame_index:1}" "${snapshot}" "${elapsed_seconds}" >&2
223
+ printf "\r\033[2K%s %s | elapsed: %ss" "${message}" "${snapshot}" "${elapsed_seconds}" >&2
195
224
  else
196
- printf "\r\033[2K%s [%s] elapsed: %ss" "${message}" "${frames:frame_index:1}" "${elapsed_seconds}" >&2
225
+ printf "\r\033[2K%s [working] | elapsed: %ss" "${message}" "${elapsed_seconds}" >&2
197
226
  fi
198
- frame_index=$(((frame_index + 1) % 4))
199
227
  sleep 0.1
200
228
  done
201
229
  ) &
@@ -2825,9 +2853,23 @@ manager_installed_names_cached() {
2825
2853
  mark_installed_packages() {
2826
2854
  local source_file="$1"
2827
2855
  local output_file="$2"
2856
+ local unique_managers_file
2857
+ local manager_counts_file
2828
2858
  local installed_file
2829
2859
  local installed_map_file
2860
+ local installed_part_file
2861
+ local manager_match_count
2862
+ local installed_match_count
2863
+ local installed_part_files=()
2864
+ local gather_pids=()
2830
2865
  local manager
2866
+ local gather_pid
2867
+
2868
+ unique_managers_file="$(mktemp "${SESSION_TMP_ROOT}/installed-managers.XXXXXX")"
2869
+ awk -F'\t' 'NF >= 1 && $1 != "" { print $1 }' "${source_file}" | awk '!seen[$0]++' >"${unique_managers_file}"
2870
+
2871
+ manager_counts_file="$(mktemp "${SESSION_TMP_ROOT}/installed-counts.XXXXXX")"
2872
+ awk -F'\t' 'NF >= 1 && $1 != "" { counts[$1]++ } END { for (mgr in counts) print mgr "\t" counts[mgr] }' "${source_file}" >"${manager_counts_file}"
2831
2873
 
2832
2874
  if [[ "${FPF_SKIP_INSTALLED_MARKERS:-0}" == "1" ]]; then
2833
2875
  awk -F'\t' '
@@ -2837,6 +2879,11 @@ mark_installed_packages() {
2837
2879
  print $1 "\t" $2 "\t " desc
2838
2880
  }
2839
2881
  ' "${source_file}" >"${output_file}"
2882
+ while IFS= read -r manager; do
2883
+ [[ -n "${manager}" ]] || continue
2884
+ loading_progress_mark_done "${manager}" "installed marker check skipped"
2885
+ done <"${unique_managers_file}"
2886
+ rm -f "${unique_managers_file}" "${manager_counts_file}"
2840
2887
  return
2841
2888
  fi
2842
2889
 
@@ -2845,13 +2892,39 @@ mark_installed_packages() {
2845
2892
 
2846
2893
  while IFS= read -r manager; do
2847
2894
  [[ -n "${manager}" ]] || continue
2848
- installed_file="$(mktemp "${SESSION_TMP_ROOT}/installed.${manager}.XXXXXX")"
2849
- manager_installed_names_cached "${manager}" "${installed_file}"
2850
- if [[ -s "${installed_file}" ]]; then
2851
- awk -F'\t' -v mgr="${manager}" 'NF > 0 && $1 != "" { print mgr "\t" $1 }' "${installed_file}" >>"${installed_map_file}"
2895
+ installed_part_file="$(mktemp "${SESSION_TMP_ROOT}/installed-map.${manager}.XXXXXX")"
2896
+ installed_part_files+=("${installed_part_file}")
2897
+
2898
+ (
2899
+ manager_match_count="$(awk -F'\t' -v mgr="${manager}" '$1 == mgr { print $2; found=1; exit } END { if (!found) print 0 }' "${manager_counts_file}")"
2900
+ if ! [[ "${manager_match_count}" =~ ^[0-9]+$ ]]; then
2901
+ manager_match_count=0
2902
+ fi
2903
+
2904
+ loading_progress_mark_running "${manager}" "marking installed status for ${manager_match_count} matches"
2905
+ installed_file="$(mktemp "${SESSION_TMP_ROOT}/installed.${manager}.XXXXXX")"
2906
+ manager_installed_names_cached "${manager}" "${installed_file}" || true
2907
+ installed_match_count=0
2908
+ if [[ -s "${installed_file}" ]]; then
2909
+ awk -F'\t' -v mgr="${manager}" 'NF > 0 && $1 != "" { print mgr "\t" $1 }' "${installed_file}" >"${installed_part_file}"
2910
+ installed_match_count="$(awk 'END { print NR + 0 }' "${installed_part_file}")"
2911
+ fi
2912
+ rm -f "${installed_file}"
2913
+ loading_progress_mark_done "${manager}" "${manager_match_count} matches, ${installed_match_count} installed"
2914
+ ) &
2915
+ gather_pids+=("$!")
2916
+ done <"${unique_managers_file}"
2917
+
2918
+ for gather_pid in "${gather_pids[@]-}"; do
2919
+ wait "${gather_pid}" || true
2920
+ done
2921
+
2922
+ for installed_part_file in "${installed_part_files[@]-}"; do
2923
+ if [[ -s "${installed_part_file}" ]]; then
2924
+ cat "${installed_part_file}" >>"${installed_map_file}"
2852
2925
  fi
2853
- rm -f "${installed_file}"
2854
- done < <(awk -F'\t' 'NF >= 1 && $1 != "" { print $1 }' "${source_file}" | awk '!seen[$0]++')
2926
+ rm -f "${installed_part_file}"
2927
+ done
2855
2928
 
2856
2929
  awk -F'\t' '
2857
2930
  FILENAME == ARGV[1] {
@@ -2870,6 +2943,7 @@ mark_installed_packages() {
2870
2943
  }
2871
2944
  ' "${installed_map_file}" "${source_file}" >"${output_file}"
2872
2945
 
2946
+ rm -f "${unique_managers_file}" "${manager_counts_file}"
2873
2947
  rm -f "${installed_map_file}"
2874
2948
  }
2875
2949
 
@@ -2921,7 +2995,7 @@ collect_search_display_rows() {
2921
2995
  local local_source_file
2922
2996
  local result_count=0
2923
2997
 
2924
- loading_progress_mark_running "${manager}" "searching package index"
2998
+ loading_progress_mark_running "${manager}" "querying package index"
2925
2999
  local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
2926
3000
  manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
2927
3001
  if [[ -s "${local_source_file}" ]]; then
@@ -2938,7 +3012,7 @@ collect_search_display_rows() {
2938
3012
  if [[ -s "${part_file}" ]]; then
2939
3013
  result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
2940
3014
  fi
2941
- loading_progress_mark_done "${manager}" "${result_count} results indexed"
3015
+ loading_progress_mark_running "${manager}" "${result_count} matches indexed; waiting for installed check"
2942
3016
  ) &
2943
3017
  gather_pids+=("$!")
2944
3018
  done
@@ -2966,6 +3040,10 @@ collect_search_display_rows() {
2966
3040
  awk -v limit="${query_limit}" 'NR <= limit' "${output_file}" >"${output_file}.limited"
2967
3041
  mv "${output_file}.limited" "${output_file}"
2968
3042
  fi
3043
+ else
3044
+ for manager in "${managers[@]-}"; do
3045
+ loading_progress_mark_done "${manager}" "0 packages matched"
3046
+ done
2969
3047
  fi
2970
3048
 
2971
3049
  rm -f "${merged_source_file}" "${merged_marked_file}"
@@ -2991,7 +3069,7 @@ collect_installed_display_rows() {
2991
3069
  local local_source_file
2992
3070
  local result_count=0
2993
3071
 
2994
- loading_progress_mark_running "${manager}" "reading installed packages"
3072
+ loading_progress_mark_running "${manager}" "reading installed package list"
2995
3073
  local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
2996
3074
  manager_installed_entries "${manager}" >"${local_source_file}" || true
2997
3075
  if [[ -s "${local_source_file}" ]]; then
@@ -3008,7 +3086,7 @@ collect_installed_display_rows() {
3008
3086
  if [[ -s "${part_file}" ]]; then
3009
3087
  result_count="$(awk 'END { print NR + 0 }' "${part_file}")"
3010
3088
  fi
3011
- loading_progress_mark_done "${manager}" "${result_count} installed entries"
3089
+ loading_progress_mark_done "${manager}" "${result_count} installed packages"
3012
3090
  ) &
3013
3091
  gather_pids+=("$!")
3014
3092
  done
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fpf-cli",
3
- "version": "1.6.36",
3
+ "version": "1.6.38",
4
4
  "description": "Cross-platform fuzzy package finder powered by fzf",
5
5
  "bin": {
6
6
  "fpf": "fpf"