fpf-cli 1.6.5 → 1.6.7

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 (2) hide show
  1. package/fpf +148 -68
  2. package/package.json +1 -1
package/fpf CHANGED
@@ -494,6 +494,9 @@ parse_args() {
494
494
  -U|--update)
495
495
  ACTION="update"
496
496
  ;;
497
+ --feed-search)
498
+ ACTION="feed-search"
499
+ ;;
497
500
  -ap|--apt)
498
501
  MANAGER_OVERRIDE="apt"
499
502
  ;;
@@ -713,15 +716,15 @@ manager_search_entries() {
713
716
  /^Name[[:space:]]+Id[[:space:]]+/ { next }
714
717
  /^[-[:space:]]+$/ { next }
715
718
  {
719
+ line = $0
720
+ sub(/^[[:space:]]+/, "", line)
716
721
  pkg = ""
717
- desc = "-"
718
- if (NF >= 2) {
719
- pkg = $2
720
- } else if (NF >= 1) {
721
- pkg = $1
722
+ n = split(line, cols, /[[:space:]][[:space:]]+/)
723
+ if (n >= 2) {
724
+ pkg = cols[2]
722
725
  }
723
726
  if (pkg != "") {
724
- print pkg "\t" desc
727
+ print pkg "\t-"
725
728
  }
726
729
  }
727
730
  '
@@ -851,17 +854,20 @@ manager_installed_entries() {
851
854
  /^Name[[:space:]]+Id[[:space:]]+/ { next }
852
855
  /^[-[:space:]]+$/ { next }
853
856
  {
857
+ line = $0
858
+ sub(/^[[:space:]]+/, "", line)
859
+
854
860
  pkg = ""
855
861
  ver = "installed"
856
- if (NF >= 3) {
857
- pkg = $2
858
- ver = $3
859
- } else if (NF >= 2) {
860
- pkg = $1
861
- ver = $2
862
- } else if (NF >= 1) {
863
- pkg = $1
862
+
863
+ n = split(line, cols, /[[:space:]][[:space:]]+/)
864
+ if (n >= 2) {
865
+ pkg = cols[2]
866
+ }
867
+ if (n >= 3 && cols[3] != "") {
868
+ ver = cols[3]
864
869
  }
870
+
865
871
  if (pkg != "") {
866
872
  print pkg "\t" ver
867
873
  }
@@ -902,9 +908,6 @@ manager_installed_entries() {
902
908
  if bun pm ls --global >/dev/null 2>&1; then
903
909
  bun pm ls --global 2>/dev/null |
904
910
  awk 'NR > 1 && NF > 0 { print $1 "\tglobal" }'
905
- elif bun pm ls >/dev/null 2>&1; then
906
- bun pm ls 2>/dev/null |
907
- awk 'NR > 1 && NF > 0 { print $1 "\tglobal" }'
908
911
  elif command_exists npm; then
909
912
  npm ls -g --depth=0 --parseable 2>/dev/null |
910
913
  awk -F'/' 'NR > 1 { print $NF "\tglobal" }'
@@ -946,6 +949,74 @@ mark_installed_packages() {
946
949
  rm -f "${installed_file}"
947
950
  }
948
951
 
952
+ collect_search_display_rows() {
953
+ local query="$1"
954
+ local output_file="$2"
955
+ shift 2
956
+ local managers=("$@")
957
+
958
+ : >"${output_file}"
959
+
960
+ local part_files=()
961
+ local gather_pids=()
962
+ local manager
963
+ local part_file
964
+ local gather_pid
965
+
966
+ for manager in "${managers[@]-}"; do
967
+ part_file="$(mktemp "${TMP_ROOT}/part.XXXXXX")"
968
+ part_files+=("${part_file}")
969
+
970
+ (
971
+ local_source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
972
+ local_marked_file="$(mktemp "${TMP_ROOT}/marked.XXXXXX")"
973
+ manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
974
+ if [[ -s "${local_source_file}" ]]; then
975
+ mark_installed_packages "${manager}" "${local_source_file}" "${local_marked_file}"
976
+ awk -F'\t' -v mgr="${manager}" '
977
+ NF >= 1 {
978
+ desc = $2
979
+ if (desc == "") desc = "-"
980
+ print mgr "\t" $1 "\t" desc
981
+ }
982
+ ' "${local_marked_file}" >"${part_file}"
983
+ fi
984
+ rm -f "${local_source_file}" "${local_marked_file}"
985
+ ) &
986
+ gather_pids+=("$!")
987
+ done
988
+
989
+ for gather_pid in "${gather_pids[@]-}"; do
990
+ wait "${gather_pid}" || true
991
+ done
992
+
993
+ for part_file in "${part_files[@]-}"; do
994
+ if [[ -s "${part_file}" ]]; then
995
+ cat "${part_file}" >>"${output_file}"
996
+ fi
997
+ rm -f "${part_file}"
998
+ done
999
+
1000
+ if [[ -s "${output_file}" ]]; then
1001
+ sort -u "${output_file}" -o "${output_file}"
1002
+ fi
1003
+ }
1004
+
1005
+ build_dynamic_reload_command() {
1006
+ local manager_override="$1"
1007
+ local script_path="${BASH_SOURCE[0]}"
1008
+
1009
+ if [[ "${script_path}" != /* ]]; then
1010
+ script_path="$(pwd)/${script_path}"
1011
+ fi
1012
+
1013
+ if [[ -n "${manager_override}" ]]; then
1014
+ printf "%q --feed-search --manager %q -- {q} 2>/dev/null || true" "${script_path}" "${manager_override}"
1015
+ else
1016
+ printf "%q --feed-search -- {q} 2>/dev/null || true" "${script_path}"
1017
+ fi
1018
+ }
1019
+
949
1020
  manager_preview_command() {
950
1021
  local manager="$1"
951
1022
 
@@ -1036,7 +1107,10 @@ manager_install() {
1036
1107
  flatpak)
1037
1108
  local pkg
1038
1109
  for pkg in "$@"; do
1039
- flatpak install -y --user flathub "${pkg}" 2>/dev/null || flatpak install -y --user "${pkg}"
1110
+ flatpak install -y --user flathub "${pkg}" 2>/dev/null ||
1111
+ flatpak install -y --user "${pkg}" 2>/dev/null ||
1112
+ run_as_root flatpak install -y flathub "${pkg}" 2>/dev/null ||
1113
+ run_as_root flatpak install -y "${pkg}"
1040
1114
  done
1041
1115
  ;;
1042
1116
  npm)
@@ -1075,7 +1149,7 @@ manager_remove() {
1075
1149
  winget)
1076
1150
  local pkg
1077
1151
  for pkg in "$@"; do
1078
- winget uninstall --id "${pkg}" --exact --disable-interactivity
1152
+ winget uninstall --id "${pkg}" --exact --source winget --disable-interactivity
1079
1153
  done
1080
1154
  ;;
1081
1155
  choco)
@@ -1088,13 +1162,13 @@ manager_remove() {
1088
1162
  run_as_root snap remove "$@"
1089
1163
  ;;
1090
1164
  flatpak)
1091
- flatpak uninstall -y --user "$@"
1165
+ flatpak uninstall -y --user "$@" 2>/dev/null || run_as_root flatpak uninstall -y "$@"
1092
1166
  ;;
1093
1167
  npm)
1094
1168
  npm uninstall -g "$@"
1095
1169
  ;;
1096
1170
  bun)
1097
- bun remove --global "$@" 2>/dev/null || bun remove "$@"
1171
+ bun remove --global "$@"
1098
1172
  ;;
1099
1173
  esac
1100
1174
  }
@@ -1186,13 +1260,13 @@ manager_update() {
1186
1260
  run_as_root snap refresh
1187
1261
  ;;
1188
1262
  flatpak)
1189
- flatpak update -y --user
1263
+ flatpak update -y --user 2>/dev/null || run_as_root flatpak update -y
1190
1264
  ;;
1191
1265
  npm)
1192
1266
  npm update -g
1193
1267
  ;;
1194
1268
  bun)
1195
- bun update --global 2>/dev/null || bun update
1269
+ bun update --global
1196
1270
  ;;
1197
1271
  esac
1198
1272
  }
@@ -1218,11 +1292,13 @@ run_fuzzy_selector() {
1218
1292
  local query="$1"
1219
1293
  local input_file="$2"
1220
1294
  local header_line="$3"
1295
+ local reload_cmd="${4:-}"
1221
1296
  local preview_cmd
1222
1297
 
1223
1298
  preview_cmd='bash -c '\''mgr="$1"; pkg="$2"; case "$mgr" in apt) apt-cache show "$pkg" 2>/dev/null; printf "\n"; dpkg -L "$pkg" 2>/dev/null ;; dnf) dnf info "$pkg" 2>/dev/null; printf "\n"; rpm -ql "$pkg" 2>/dev/null ;; pacman) pacman -Si "$pkg" 2>/dev/null; printf "\n"; pacman -Fl "$pkg" 2>/dev/null | awk "{print \$2}" ;; zypper) zypper --non-interactive info "$pkg" 2>/dev/null ;; emerge) emerge --search --color=n "$pkg" 2>/dev/null ;; brew) brew info "$pkg" 2>/dev/null ;; winget) winget show --id "$pkg" --exact --source winget --accept-source-agreements --disable-interactivity 2>/dev/null ;; choco) choco info "$pkg" 2>/dev/null ;; scoop) scoop info "$pkg" 2>/dev/null ;; snap) snap info "$pkg" 2>/dev/null ;; flatpak) flatpak info "$pkg" 2>/dev/null || flatpak remote-info flathub "$pkg" 2>/dev/null ;; npm) npm view "$pkg" 2>/dev/null ;; bun) bun info "$pkg" 2>/dev/null || npm view "$pkg" 2>/dev/null ;; esac'\'' _ {1} {2}'
1224
1299
 
1225
- fzf -q "${query}" -e -m \
1300
+ local -a fzf_args=()
1301
+ fzf_args=(-q "${query}" -m \
1226
1302
  --delimiter=$'\t' \
1227
1303
  --with-nth=1,2,3 \
1228
1304
  --preview="${preview_cmd}" \
@@ -1237,8 +1313,15 @@ run_fuzzy_selector() {
1237
1313
  --bind=ctrl-h:preview:"cat ${HELP_FILE}" \
1238
1314
  --bind='ctrl-/:change-preview-window(hidden|)' \
1239
1315
  --bind=ctrl-n:next-selected,ctrl-b:prev-selected \
1240
- --bind='focus:transform-preview-label:echo {1}: {2}' \
1241
- <"${input_file}"
1316
+ --bind='focus:transform-preview-label:echo {1}: {2}')
1317
+
1318
+ if [[ -n "${reload_cmd}" ]]; then
1319
+ fzf_args+=(--disabled --bind="start:reload:${reload_cmd}" --bind="change:reload:${reload_cmd}")
1320
+ else
1321
+ fzf_args+=(-e)
1322
+ fi
1323
+
1324
+ fzf "${fzf_args[@]}" <"${input_file}"
1242
1325
  }
1243
1326
 
1244
1327
  main() {
@@ -1304,22 +1387,33 @@ main() {
1304
1387
  exit 0
1305
1388
  fi
1306
1389
 
1307
- ensure_fzf "${managers[@]-}"
1308
-
1309
1390
  local display_file
1310
1391
  display_file="$(mktemp "${TMP_ROOT}/display.XXXXXX")"
1311
1392
  : >"${display_file}"
1312
1393
 
1313
- local part_files=()
1314
- local gather_pids=()
1315
- local part_file
1316
- local gather_pid
1394
+ if [[ "${ACTION}" == "feed-search" ]]; then
1395
+ collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"
1396
+ if [[ -s "${display_file}" ]]; then
1397
+ cat "${display_file}"
1398
+ fi
1399
+ rm -f "${display_file}"
1400
+ exit 0
1401
+ fi
1317
1402
 
1318
- for manager in "${managers[@]-}"; do
1319
- part_file="$(mktemp "${TMP_ROOT}/part.XXXXXX")"
1320
- part_files+=("${part_file}")
1403
+ ensure_fzf "${managers[@]-}"
1404
+
1405
+ if [[ "${ACTION}" == "search" ]]; then
1406
+ collect_search_display_rows "${query}" "${display_file}" "${managers[@]-}"
1407
+ else
1408
+ local part_files=()
1409
+ local gather_pids=()
1410
+ local part_file
1411
+ local gather_pid
1412
+
1413
+ for manager in "${managers[@]-}"; do
1414
+ part_file="$(mktemp "${TMP_ROOT}/part.XXXXXX")"
1415
+ part_files+=("${part_file}")
1321
1416
 
1322
- if [[ "${ACTION}" == "list" || "${ACTION}" == "remove" ]]; then
1323
1417
  (
1324
1418
  local_source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
1325
1419
  manager_installed_entries "${manager}" >"${local_source_file}" || true
@@ -1335,41 +1429,22 @@ main() {
1335
1429
  rm -f "${local_source_file}"
1336
1430
  ) &
1337
1431
  gather_pids+=("$!")
1338
- continue
1339
- fi
1432
+ done
1340
1433
 
1341
- (
1342
- local_source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
1343
- local_marked_file="$(mktemp "${TMP_ROOT}/marked.XXXXXX")"
1344
- manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
1345
- if [[ -s "${local_source_file}" ]]; then
1346
- mark_installed_packages "${manager}" "${local_source_file}" "${local_marked_file}"
1347
- awk -F'\t' -v mgr="${manager}" '
1348
- NF >= 1 {
1349
- desc = $2
1350
- if (desc == "") desc = "-"
1351
- print mgr "\t" $1 "\t" desc
1352
- }
1353
- ' "${local_marked_file}" >"${part_file}"
1354
- fi
1355
- rm -f "${local_source_file}" "${local_marked_file}"
1356
- ) &
1357
- gather_pids+=("$!")
1358
- done
1434
+ for gather_pid in "${gather_pids[@]-}"; do
1435
+ wait "${gather_pid}" || true
1436
+ done
1359
1437
 
1360
- for gather_pid in "${gather_pids[@]-}"; do
1361
- wait "${gather_pid}" || true
1362
- done
1438
+ for part_file in "${part_files[@]-}"; do
1439
+ if [[ -s "${part_file}" ]]; then
1440
+ cat "${part_file}" >>"${display_file}"
1441
+ fi
1442
+ rm -f "${part_file}"
1443
+ done
1363
1444
 
1364
- for part_file in "${part_files[@]-}"; do
1365
- if [[ -s "${part_file}" ]]; then
1366
- cat "${part_file}" >>"${display_file}"
1445
+ if [[ -s "${display_file}" ]]; then
1446
+ sort -u "${display_file}" -o "${display_file}"
1367
1447
  fi
1368
- rm -f "${part_file}"
1369
- done
1370
-
1371
- if [[ -s "${display_file}" ]]; then
1372
- sort -u "${display_file}" -o "${display_file}"
1373
1448
  fi
1374
1449
 
1375
1450
  if [[ ! -s "${display_file}" ]]; then
@@ -1393,8 +1468,13 @@ main() {
1393
1468
  ;;
1394
1469
  esac
1395
1470
 
1471
+ local reload_cmd=""
1472
+ if [[ "${ACTION}" == "search" && -z "${query}" ]]; then
1473
+ reload_cmd="$(build_dynamic_reload_command "${MANAGER_OVERRIDE}")"
1474
+ fi
1475
+
1396
1476
  local selected
1397
- selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" || true)"
1477
+ selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" "${reload_cmd}" || true)"
1398
1478
 
1399
1479
  rm -f "${display_file}"
1400
1480
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fpf-cli",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "Cross-platform fuzzy package finder powered by fzf",
5
5
  "bin": {
6
6
  "fpf": "fpf"