fpf-cli 1.6.7 → 1.6.8

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 +3 -0
  2. package/fpf +65 -70
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -68,6 +68,7 @@ For no-query startup (`fpf`), each manager uses a lighter default query and per-
68
68
  - `-l, --list-installed` list installed packages
69
69
  - `-R, --remove` remove selected packages
70
70
  - `-U, --update` run update/upgrade flow
71
+ - `-v, --version` print version and exit
71
72
  - `-h, --help` show help
72
73
 
73
74
  ## Keybinds
@@ -78,6 +79,8 @@ For no-query startup (`fpf`), each manager uses a lighter default query and per-
78
79
  - `ctrl-n` next selected item
79
80
  - `ctrl-b` previous selected item
80
81
 
82
+ Installed packages are marked with `*` in the result list.
83
+
81
84
  ## Notes
82
85
 
83
86
  - Requires: `bash` + `fzf`
package/fpf CHANGED
@@ -3,9 +3,11 @@
3
3
  set -euo pipefail
4
4
 
5
5
  SCRIPT_NAME="fpf"
6
+ SCRIPT_VERSION="1.6.8"
6
7
  TMP_ROOT="${TMPDIR:-/tmp}/fpf"
7
- HELP_FILE="${TMP_ROOT}/help"
8
- KBINDS_FILE="${TMP_ROOT}/keybinds"
8
+ SESSION_TMP_ROOT=""
9
+ HELP_FILE=""
10
+ KBINDS_FILE=""
9
11
 
10
12
  ACTION="search"
11
13
  MANAGER_OVERRIDE=""
@@ -28,6 +30,22 @@ ensure_tmp_root() {
28
30
  mkdir -p "${TMP_ROOT}"
29
31
  }
30
32
 
33
+ initialize_session_tmp_root() {
34
+ if [[ -n "${SESSION_TMP_ROOT}" ]]; then
35
+ return
36
+ fi
37
+
38
+ SESSION_TMP_ROOT="$(mktemp -d "${TMP_ROOT}/session.XXXXXX")"
39
+ HELP_FILE="${SESSION_TMP_ROOT}/help"
40
+ KBINDS_FILE="${SESSION_TMP_ROOT}/keybinds"
41
+ }
42
+
43
+ cleanup_session_tmp_root() {
44
+ if [[ -n "${SESSION_TMP_ROOT}" && -d "${SESSION_TMP_ROOT}" ]]; then
45
+ rm -rf "${SESSION_TMP_ROOT}"
46
+ fi
47
+ }
48
+
31
49
  run_as_root() {
32
50
  if [[ "${EUID}" -eq 0 ]]; then
33
51
  "$@"
@@ -412,7 +430,7 @@ build_help_file() {
412
430
  local default_managers="$1"
413
431
 
414
432
  cat >"${HELP_FILE}" <<EOF
415
- ${SCRIPT_NAME} - ultimate fuzzy package finder
433
+ ${SCRIPT_NAME} - fuzzy package finder
416
434
 
417
435
  Syntax:
418
436
  ${SCRIPT_NAME} [manager option] [action option] [query]
@@ -428,6 +446,7 @@ Action options:
428
446
  -l, --list-installed Fuzzy-search installed packages and show details
429
447
  -R, --remove Fuzzy-search installed packages and remove selected
430
448
  -U, --update Run manager update/upgrade flow
449
+ -v, --version Print version and exit
431
450
  -h, --help Show this help
432
451
 
433
452
  Manager options (one or two-letter style):
@@ -479,12 +498,19 @@ print_help() {
479
498
  cat "${HELP_FILE}"
480
499
  }
481
500
 
501
+ print_version() {
502
+ printf "%s %s\n" "${SCRIPT_NAME}" "${SCRIPT_VERSION}"
503
+ }
504
+
482
505
  parse_args() {
483
506
  while (($#)); do
484
507
  case "$1" in
485
508
  -h|--help)
486
509
  ACTION="help"
487
510
  ;;
511
+ -v|--version)
512
+ ACTION="version"
513
+ ;;
488
514
  -l|--list-installed)
489
515
  ACTION="list"
490
516
  ;;
@@ -928,7 +954,7 @@ mark_installed_packages() {
928
954
  local output_file="$3"
929
955
  local installed_file
930
956
 
931
- installed_file="$(mktemp "${TMP_ROOT}/installed.XXXXXX")"
957
+ installed_file="$(mktemp "${SESSION_TMP_ROOT}/installed.XXXXXX")"
932
958
  manager_installed_names "${manager}" >"${installed_file}" 2>/dev/null || true
933
959
 
934
960
  awk -F'\t' '
@@ -939,7 +965,7 @@ mark_installed_packages() {
939
965
  next
940
966
  }
941
967
  {
942
- mark = (installed[$1] ? "* " : " ")
968
+ mark = (installed[$1] ? "\033[32m*\033[0m " : " ")
943
969
  desc = $2
944
970
  if (desc == "") desc = "-"
945
971
  print $1 "\t" mark desc
@@ -964,12 +990,12 @@ collect_search_display_rows() {
964
990
  local gather_pid
965
991
 
966
992
  for manager in "${managers[@]-}"; do
967
- part_file="$(mktemp "${TMP_ROOT}/part.XXXXXX")"
993
+ part_file="$(mktemp "${SESSION_TMP_ROOT}/part.XXXXXX")"
968
994
  part_files+=("${part_file}")
969
995
 
970
996
  (
971
- local_source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
972
- local_marked_file="$(mktemp "${TMP_ROOT}/marked.XXXXXX")"
997
+ local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
998
+ local_marked_file="$(mktemp "${SESSION_TMP_ROOT}/marked.XXXXXX")"
973
999
  manager_search_entries "${manager}" "${query}" >"${local_source_file}" || true
974
1000
  if [[ -s "${local_source_file}" ]]; then
975
1001
  mark_installed_packages "${manager}" "${local_source_file}" "${local_marked_file}"
@@ -1017,52 +1043,6 @@ build_dynamic_reload_command() {
1017
1043
  fi
1018
1044
  }
1019
1045
 
1020
- manager_preview_command() {
1021
- local manager="$1"
1022
-
1023
- case "${manager}" in
1024
- apt)
1025
- printf '%s' 'pkg={1}; apt-cache show "$pkg" 2>/dev/null; printf "\n"; dpkg -L "$pkg" 2>/dev/null'
1026
- ;;
1027
- dnf)
1028
- printf '%s' 'pkg={1}; dnf info "$pkg" 2>/dev/null; printf "\n"; rpm -ql "$pkg" 2>/dev/null'
1029
- ;;
1030
- pacman)
1031
- printf '%s' 'pkg={1}; pacman -Si "$pkg" 2>/dev/null; printf "\n"; pacman -Fl "$pkg" 2>/dev/null | awk "{print \$2}"'
1032
- ;;
1033
- zypper)
1034
- printf '%s' 'pkg={1}; zypper --non-interactive info "$pkg" 2>/dev/null'
1035
- ;;
1036
- emerge)
1037
- printf '%s' 'pkg={1}; emerge --search --color=n "$pkg" 2>/dev/null'
1038
- ;;
1039
- brew)
1040
- printf '%s' 'pkg={1}; brew info "$pkg" 2>/dev/null'
1041
- ;;
1042
- winget)
1043
- printf '%s' 'pkg={1}; winget show --id "$pkg" --exact --source winget --accept-source-agreements --disable-interactivity 2>/dev/null'
1044
- ;;
1045
- choco)
1046
- printf '%s' 'pkg={1}; choco info "$pkg" 2>/dev/null'
1047
- ;;
1048
- scoop)
1049
- printf '%s' 'pkg={1}; scoop info "$pkg" 2>/dev/null'
1050
- ;;
1051
- snap)
1052
- printf '%s' 'pkg={1}; snap info "$pkg" 2>/dev/null'
1053
- ;;
1054
- flatpak)
1055
- printf '%s' 'pkg={1}; flatpak info "$pkg" 2>/dev/null || flatpak remote-info flathub "$pkg" 2>/dev/null'
1056
- ;;
1057
- npm)
1058
- printf '%s' 'pkg={1}; npm view "$pkg" 2>/dev/null'
1059
- ;;
1060
- bun)
1061
- printf '%s' 'pkg={1}; bun info "$pkg" 2>/dev/null || npm view "$pkg" 2>/dev/null'
1062
- ;;
1063
- esac
1064
- }
1065
-
1066
1046
  manager_install() {
1067
1047
  local manager="$1"
1068
1048
  shift
@@ -1306,14 +1286,16 @@ run_fuzzy_selector() {
1306
1286
  --layout=reverse \
1307
1287
  --marker='>>' \
1308
1288
  --header="${header_line}" \
1309
- --info=hidden \
1289
+ --info=inline-right \
1290
+ --ansi \
1310
1291
  --margin="2%,1%,2%,1%" \
1311
1292
  --cycle \
1293
+ --tiebreak=begin,chunk,length \
1312
1294
  --bind=ctrl-k:preview:"cat ${KBINDS_FILE}" \
1313
1295
  --bind=ctrl-h:preview:"cat ${HELP_FILE}" \
1314
1296
  --bind='ctrl-/:change-preview-window(hidden|)' \
1315
1297
  --bind=ctrl-n:next-selected,ctrl-b:prev-selected \
1316
- --bind='focus:transform-preview-label:echo {1}: {2}')
1298
+ --bind='focus:transform-preview-label:echo [{1}] {2}')
1317
1299
 
1318
1300
  if [[ -n "${reload_cmd}" ]]; then
1319
1301
  fzf_args+=(--disabled --bind="start:reload:${reload_cmd}" --bind="change:reload:${reload_cmd}")
@@ -1326,9 +1308,16 @@ run_fuzzy_selector() {
1326
1308
 
1327
1309
  main() {
1328
1310
  ensure_tmp_root
1311
+ initialize_session_tmp_root
1312
+ trap cleanup_session_tmp_root EXIT
1329
1313
 
1330
1314
  parse_args "$@"
1331
1315
 
1316
+ if [[ "${ACTION}" == "version" ]]; then
1317
+ print_version
1318
+ exit 0
1319
+ fi
1320
+
1332
1321
  local detected_manager
1333
1322
  local detected_managers=()
1334
1323
  while IFS= read -r detected_manager; do
@@ -1374,8 +1363,11 @@ main() {
1374
1363
  local query
1375
1364
  query="$(join_query)"
1376
1365
 
1377
- if [[ "${ACTION}" == "update" ]]; then
1366
+ if [[ "${ACTION}" != "feed-search" ]]; then
1378
1367
  log "Using manager(s): ${manager_display}"
1368
+ fi
1369
+
1370
+ if [[ "${ACTION}" == "update" ]]; then
1379
1371
  if confirm_action "Run update/upgrade for ${manager_display}?"; then
1380
1372
  for manager in "${managers[@]-}"; do
1381
1373
  log "Updating with $(manager_label "${manager}")"
@@ -1388,7 +1380,7 @@ main() {
1388
1380
  fi
1389
1381
 
1390
1382
  local display_file
1391
- display_file="$(mktemp "${TMP_ROOT}/display.XXXXXX")"
1383
+ display_file="$(mktemp "${SESSION_TMP_ROOT}/display.XXXXXX")"
1392
1384
  : >"${display_file}"
1393
1385
 
1394
1386
  if [[ "${ACTION}" == "feed-search" ]]; then
@@ -1411,14 +1403,14 @@ main() {
1411
1403
  local gather_pid
1412
1404
 
1413
1405
  for manager in "${managers[@]-}"; do
1414
- part_file="$(mktemp "${TMP_ROOT}/part.XXXXXX")"
1415
- part_files+=("${part_file}")
1416
-
1417
- (
1418
- local_source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
1419
- manager_installed_entries "${manager}" >"${local_source_file}" || true
1420
- if [[ -s "${local_source_file}" ]]; then
1421
- awk -F'\t' -v mgr="${manager}" '
1406
+ part_file="$(mktemp "${SESSION_TMP_ROOT}/part.XXXXXX")"
1407
+ part_files+=("${part_file}")
1408
+
1409
+ (
1410
+ local_source_file="$(mktemp "${SESSION_TMP_ROOT}/source.XXXXXX")"
1411
+ manager_installed_entries "${manager}" >"${local_source_file}" || true
1412
+ if [[ -s "${local_source_file}" ]]; then
1413
+ awk -F'\t' -v mgr="${manager}" '
1422
1414
  NF >= 1 {
1423
1415
  desc = $2
1424
1416
  if (desc == "") desc = "-"
@@ -1449,13 +1441,16 @@ main() {
1449
1441
 
1450
1442
  if [[ ! -s "${display_file}" ]]; then
1451
1443
  rm -f "${display_file}"
1452
- die "No packages found for manager(s) '${manager_display}' and query '${query}'"
1444
+ if [[ -n "${query}" ]]; then
1445
+ die "No packages found for ${manager_display} matching '${query}'. Try a broader query or --manager."
1446
+ fi
1447
+ die "No packages found for ${manager_display}. Try adding a query or using --manager."
1453
1448
  fi
1454
1449
 
1455
1450
  local header
1456
1451
  case "${ACTION}" in
1457
1452
  search)
1458
- header="Select package(s) to install with ${manager_display} (TAB to multi-select)"
1453
+ header="Select package(s) to install with ${manager_display} (TAB to multi-select, * = installed)"
1459
1454
  ;;
1460
1455
  list)
1461
1456
  header="Select installed package(s) to inspect from ${manager_display}"
@@ -1479,7 +1474,7 @@ main() {
1479
1474
  rm -f "${display_file}"
1480
1475
 
1481
1476
  if [[ -z "${selected}" ]]; then
1482
- log "No package selected"
1477
+ log "Selection canceled"
1483
1478
  exit 0
1484
1479
  fi
1485
1480
 
@@ -1497,7 +1492,7 @@ main() {
1497
1492
  done <<<"${selected}"
1498
1493
 
1499
1494
  if [[ "${#selected_packages[@]}" -eq 0 ]]; then
1500
- log "No package selected"
1495
+ log "Selection canceled"
1501
1496
  exit 0
1502
1497
  fi
1503
1498
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fpf-cli",
3
- "version": "1.6.7",
3
+ "version": "1.6.8",
4
4
  "description": "Cross-platform fuzzy package finder powered by fzf",
5
5
  "bin": {
6
6
  "fpf": "fpf"