fpf-cli 1.6.3 → 1.6.5

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 -6
  2. package/fpf +111 -66
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -34,13 +34,9 @@ fpf -U
34
34
 
35
35
  By default, `fpf` auto-detects your package manager.
36
36
 
37
- On macOS, default auto mode uses `brew`, `npm`, and `bun` together.
37
+ On every OS, default auto mode now includes all supported package managers that are detected on your system in one combined list.
38
38
 
39
- On macOS with no query (`fpf`), startup uses a lighter default search for `brew` and `bun` so you still get installable packages without the huge initial catalog load.
40
-
41
- On Linux, default auto mode uses your distro manager plus installed cross-platform managers (`snap`, `flatpak`, `brew`, `npm`, `bun`).
42
-
43
- On Windows (Git Bash / MSYS / Cygwin), default auto mode uses installed Windows managers (`winget`, `choco`, `scoop`) plus `npm` and `bun`.
39
+ For no-query startup (`fpf`), each manager uses a lighter default query and per-manager result cap to keep startup responsive.
44
40
 
45
41
  ## Supported Managers
46
42
 
package/fpf CHANGED
@@ -346,9 +346,9 @@ detect_default_manager() {
346
346
  }
347
347
 
348
348
  detect_default_managers() {
349
- local os
350
349
  local emitted=""
351
350
  local primary_manager=""
351
+ local manager
352
352
 
353
353
  add_detected_manager() {
354
354
  local manager_name="$1"
@@ -364,46 +364,13 @@ detect_default_managers() {
364
364
  fi
365
365
  }
366
366
 
367
- os="$(uname -s)"
368
-
369
- if [[ "${os}" == "Darwin" ]]; then
370
- add_detected_manager "brew"
371
- add_detected_manager "npm"
372
- add_detected_manager "bun"
373
- if [[ -n "${emitted}" ]]; then
374
- return
375
- fi
376
- fi
377
-
378
- if [[ "${os}" == MINGW* || "${os}" == MSYS* || "${os}" == CYGWIN* || "${os}" == "Windows_NT" ]]; then
379
- add_detected_manager "winget"
380
- add_detected_manager "choco"
381
- add_detected_manager "scoop"
382
- add_detected_manager "npm"
383
- add_detected_manager "bun"
384
- if [[ -n "${emitted}" ]]; then
385
- return
386
- fi
387
- fi
388
-
389
- if [[ "${os}" == "Linux" ]]; then
390
- primary_manager="$(detect_default_manager)"
391
- add_detected_manager "${primary_manager}"
392
-
393
- add_detected_manager "snap"
394
- add_detected_manager "flatpak"
395
- add_detected_manager "brew"
396
- add_detected_manager "npm"
397
- add_detected_manager "bun"
398
-
399
- if [[ -n "${emitted}" ]]; then
400
- return
401
- fi
402
- fi
403
-
404
367
  primary_manager="$(detect_default_manager)"
405
368
  add_detected_manager "${primary_manager}"
406
369
 
370
+ for manager in apt dnf pacman zypper emerge brew winget choco scoop snap flatpak npm bun; do
371
+ add_detected_manager "${manager}"
372
+ done
373
+
407
374
  if [[ -n "${emitted}" ]]; then
408
375
  return
409
376
  fi
@@ -612,10 +579,52 @@ join_query() {
612
579
  printf "%s" "${query}"
613
580
  }
614
581
 
582
+ query_is_single_token() {
583
+ local query="$1"
584
+ [[ -n "${query}" && "${query}" != *[[:space:]]* ]]
585
+ }
586
+
587
+ exact_match_entry() {
588
+ local manager="$1"
589
+ local query="$2"
590
+
591
+ if ! query_is_single_token "${query}"; then
592
+ return 0
593
+ fi
594
+
595
+ case "${manager}" in
596
+ brew)
597
+ if brew info --formula "${query}" >/dev/null 2>&1 || brew info --cask "${query}" >/dev/null 2>&1; then
598
+ printf "%s\t-\n" "${query}"
599
+ fi
600
+ ;;
601
+ npm|bun)
602
+ if command_exists npm && npm view "${query}" name >/dev/null 2>&1; then
603
+ printf "%s\t-\n" "${query}"
604
+ fi
605
+ ;;
606
+ esac
607
+ }
608
+
615
609
  manager_search_entries() {
616
610
  local manager="$1"
617
611
  local query="$2"
618
612
  local effective_query="${query}"
613
+ local npm_search_limit=500
614
+ local line_limit=0
615
+
616
+ if [[ -z "${query}" ]]; then
617
+ npm_search_limit="${FPF_NO_QUERY_NPM_LIMIT:-120}"
618
+ line_limit="${FPF_NO_QUERY_RESULT_LIMIT:-200}"
619
+ fi
620
+
621
+ if ! [[ "${npm_search_limit}" =~ ^[0-9]+$ ]] || [[ "${npm_search_limit}" -eq 0 ]]; then
622
+ npm_search_limit=500
623
+ fi
624
+
625
+ if ! [[ "${line_limit}" =~ ^[0-9]+$ ]]; then
626
+ line_limit=0
627
+ fi
619
628
 
620
629
  if [[ -z "${effective_query}" ]]; then
621
630
  case "${manager}" in
@@ -626,7 +635,7 @@ manager_search_entries() {
626
635
  effective_query="aa"
627
636
  ;;
628
637
  winget)
629
- effective_query="a"
638
+ effective_query="aa"
630
639
  ;;
631
640
  esac
632
641
  fi
@@ -691,8 +700,11 @@ manager_search_entries() {
691
700
  '
692
701
  ;;
693
702
  brew)
694
- brew search "${effective_query}" 2>/dev/null |
695
- awk 'NF > 0 { print $1 "\t-" }'
703
+ {
704
+ brew search "${effective_query}" 2>/dev/null |
705
+ awk 'NF > 0 && $1 != "==>" { print $1 "\t-" }'
706
+ exact_match_entry "${manager}" "${query}"
707
+ }
696
708
  ;;
697
709
  winget)
698
710
  winget search "${effective_query}" --source winget --accept-source-agreements --disable-interactivity 2>/dev/null |
@@ -762,8 +774,11 @@ manager_search_entries() {
762
774
  fi
763
775
  ;;
764
776
  npm)
765
- npm search "${effective_query}" --searchlimit=200 --parseable 2>/dev/null |
766
- awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
777
+ {
778
+ npm search "${effective_query}" --searchlimit="${npm_search_limit}" --parseable 2>/dev/null |
779
+ awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
780
+ exact_match_entry "${manager}" "${query}"
781
+ }
767
782
  ;;
768
783
  bun)
769
784
  {
@@ -771,12 +786,19 @@ manager_search_entries() {
771
786
  bun search "${effective_query}" 2>/dev/null |
772
787
  awk 'NR > 1 && NF > 0 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }'
773
788
  elif command_exists npm; then
774
- npm search "${effective_query}" --searchlimit=200 --parseable 2>/dev/null |
789
+ npm search "${effective_query}" --searchlimit="${npm_search_limit}" --parseable 2>/dev/null |
775
790
  awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
776
791
  fi
792
+ exact_match_entry "${manager}" "${query}"
777
793
  } || true
778
794
  ;;
779
- esac | awk -F'\t' 'NF >= 1 { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' | sort -u || true
795
+ esac | awk -F'\t' 'NF >= 1 { if ($2 == "") $2 = "-"; print $1 "\t" $2 }' | sort -u | {
796
+ if [[ "${line_limit}" -gt 0 ]]; then
797
+ awk -v limit="${line_limit}" 'NR <= limit'
798
+ else
799
+ cat
800
+ fi
801
+ } || true
780
802
  }
781
803
 
782
804
  manager_installed_entries() {
@@ -1288,39 +1310,62 @@ main() {
1288
1310
  display_file="$(mktemp "${TMP_ROOT}/display.XXXXXX")"
1289
1311
  : >"${display_file}"
1290
1312
 
1291
- local source_file
1292
- local marked_file
1313
+ local part_files=()
1314
+ local gather_pids=()
1315
+ local part_file
1316
+ local gather_pid
1317
+
1293
1318
  for manager in "${managers[@]-}"; do
1294
- source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
1319
+ part_file="$(mktemp "${TMP_ROOT}/part.XXXXXX")"
1320
+ part_files+=("${part_file}")
1295
1321
 
1296
1322
  if [[ "${ACTION}" == "list" || "${ACTION}" == "remove" ]]; then
1297
- manager_installed_entries "${manager}" >"${source_file}" || true
1298
- if [[ -s "${source_file}" ]]; then
1323
+ (
1324
+ local_source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
1325
+ manager_installed_entries "${manager}" >"${local_source_file}" || true
1326
+ if [[ -s "${local_source_file}" ]]; then
1327
+ awk -F'\t' -v mgr="${manager}" '
1328
+ NF >= 1 {
1329
+ desc = $2
1330
+ if (desc == "") desc = "-"
1331
+ print mgr "\t" $1 "\t" desc
1332
+ }
1333
+ ' "${local_source_file}" >"${part_file}"
1334
+ fi
1335
+ rm -f "${local_source_file}"
1336
+ ) &
1337
+ gather_pids+=("$!")
1338
+ continue
1339
+ fi
1340
+
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}"
1299
1347
  awk -F'\t' -v mgr="${manager}" '
1300
1348
  NF >= 1 {
1301
1349
  desc = $2
1302
1350
  if (desc == "") desc = "-"
1303
1351
  print mgr "\t" $1 "\t" desc
1304
1352
  }
1305
- ' "${source_file}" >>"${display_file}"
1353
+ ' "${local_marked_file}" >"${part_file}"
1306
1354
  fi
1307
- rm -f "${source_file}"
1308
- continue
1309
- fi
1355
+ rm -f "${local_source_file}" "${local_marked_file}"
1356
+ ) &
1357
+ gather_pids+=("$!")
1358
+ done
1359
+
1360
+ for gather_pid in "${gather_pids[@]-}"; do
1361
+ wait "${gather_pid}" || true
1362
+ done
1310
1363
 
1311
- marked_file="$(mktemp "${TMP_ROOT}/marked.XXXXXX")"
1312
- manager_search_entries "${manager}" "${query}" >"${source_file}" || true
1313
- if [[ -s "${source_file}" ]]; then
1314
- mark_installed_packages "${manager}" "${source_file}" "${marked_file}"
1315
- awk -F'\t' -v mgr="${manager}" '
1316
- NF >= 1 {
1317
- desc = $2
1318
- if (desc == "") desc = "-"
1319
- print mgr "\t" $1 "\t" desc
1320
- }
1321
- ' "${marked_file}" >>"${display_file}"
1364
+ for part_file in "${part_files[@]-}"; do
1365
+ if [[ -s "${part_file}" ]]; then
1366
+ cat "${part_file}" >>"${display_file}"
1322
1367
  fi
1323
- rm -f "${source_file}" "${marked_file}"
1368
+ rm -f "${part_file}"
1324
1369
  done
1325
1370
 
1326
1371
  if [[ -s "${display_file}" ]]; then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fpf-cli",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
4
4
  "description": "Cross-platform fuzzy package finder powered by fzf",
5
5
  "bin": {
6
6
  "fpf": "fpf"