fpf-cli 1.6.6 → 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.
- package/README.md +3 -0
- package/fpf +91 -93
- 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
|
-
|
|
8
|
-
|
|
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} -
|
|
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
|
;;
|
|
@@ -716,15 +742,15 @@ manager_search_entries() {
|
|
|
716
742
|
/^Name[[:space:]]+Id[[:space:]]+/ { next }
|
|
717
743
|
/^[-[:space:]]+$/ { next }
|
|
718
744
|
{
|
|
745
|
+
line = $0
|
|
746
|
+
sub(/^[[:space:]]+/, "", line)
|
|
719
747
|
pkg = ""
|
|
720
|
-
|
|
721
|
-
if (
|
|
722
|
-
pkg =
|
|
723
|
-
} else if (NF >= 1) {
|
|
724
|
-
pkg = $1
|
|
748
|
+
n = split(line, cols, /[[:space:]][[:space:]]+/)
|
|
749
|
+
if (n >= 2) {
|
|
750
|
+
pkg = cols[2]
|
|
725
751
|
}
|
|
726
752
|
if (pkg != "") {
|
|
727
|
-
print pkg "\t"
|
|
753
|
+
print pkg "\t-"
|
|
728
754
|
}
|
|
729
755
|
}
|
|
730
756
|
'
|
|
@@ -854,17 +880,20 @@ manager_installed_entries() {
|
|
|
854
880
|
/^Name[[:space:]]+Id[[:space:]]+/ { next }
|
|
855
881
|
/^[-[:space:]]+$/ { next }
|
|
856
882
|
{
|
|
883
|
+
line = $0
|
|
884
|
+
sub(/^[[:space:]]+/, "", line)
|
|
885
|
+
|
|
857
886
|
pkg = ""
|
|
858
887
|
ver = "installed"
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
pkg = $1
|
|
864
|
-
ver = $2
|
|
865
|
-
} else if (NF >= 1) {
|
|
866
|
-
pkg = $1
|
|
888
|
+
|
|
889
|
+
n = split(line, cols, /[[:space:]][[:space:]]+/)
|
|
890
|
+
if (n >= 2) {
|
|
891
|
+
pkg = cols[2]
|
|
867
892
|
}
|
|
893
|
+
if (n >= 3 && cols[3] != "") {
|
|
894
|
+
ver = cols[3]
|
|
895
|
+
}
|
|
896
|
+
|
|
868
897
|
if (pkg != "") {
|
|
869
898
|
print pkg "\t" ver
|
|
870
899
|
}
|
|
@@ -905,9 +934,6 @@ manager_installed_entries() {
|
|
|
905
934
|
if bun pm ls --global >/dev/null 2>&1; then
|
|
906
935
|
bun pm ls --global 2>/dev/null |
|
|
907
936
|
awk 'NR > 1 && NF > 0 { print $1 "\tglobal" }'
|
|
908
|
-
elif bun pm ls >/dev/null 2>&1; then
|
|
909
|
-
bun pm ls 2>/dev/null |
|
|
910
|
-
awk 'NR > 1 && NF > 0 { print $1 "\tglobal" }'
|
|
911
937
|
elif command_exists npm; then
|
|
912
938
|
npm ls -g --depth=0 --parseable 2>/dev/null |
|
|
913
939
|
awk -F'/' 'NR > 1 { print $NF "\tglobal" }'
|
|
@@ -928,7 +954,7 @@ mark_installed_packages() {
|
|
|
928
954
|
local output_file="$3"
|
|
929
955
|
local installed_file
|
|
930
956
|
|
|
931
|
-
installed_file="$(mktemp "${
|
|
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 "${
|
|
993
|
+
part_file="$(mktemp "${SESSION_TMP_ROOT}/part.XXXXXX")"
|
|
968
994
|
part_files+=("${part_file}")
|
|
969
995
|
|
|
970
996
|
(
|
|
971
|
-
local_source_file="$(mktemp "${
|
|
972
|
-
local_marked_file="$(mktemp "${
|
|
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
|
|
@@ -1107,7 +1087,10 @@ manager_install() {
|
|
|
1107
1087
|
flatpak)
|
|
1108
1088
|
local pkg
|
|
1109
1089
|
for pkg in "$@"; do
|
|
1110
|
-
flatpak install -y --user flathub "${pkg}" 2>/dev/null ||
|
|
1090
|
+
flatpak install -y --user flathub "${pkg}" 2>/dev/null ||
|
|
1091
|
+
flatpak install -y --user "${pkg}" 2>/dev/null ||
|
|
1092
|
+
run_as_root flatpak install -y flathub "${pkg}" 2>/dev/null ||
|
|
1093
|
+
run_as_root flatpak install -y "${pkg}"
|
|
1111
1094
|
done
|
|
1112
1095
|
;;
|
|
1113
1096
|
npm)
|
|
@@ -1146,7 +1129,7 @@ manager_remove() {
|
|
|
1146
1129
|
winget)
|
|
1147
1130
|
local pkg
|
|
1148
1131
|
for pkg in "$@"; do
|
|
1149
|
-
winget uninstall --id "${pkg}" --exact --disable-interactivity
|
|
1132
|
+
winget uninstall --id "${pkg}" --exact --source winget --disable-interactivity
|
|
1150
1133
|
done
|
|
1151
1134
|
;;
|
|
1152
1135
|
choco)
|
|
@@ -1159,13 +1142,13 @@ manager_remove() {
|
|
|
1159
1142
|
run_as_root snap remove "$@"
|
|
1160
1143
|
;;
|
|
1161
1144
|
flatpak)
|
|
1162
|
-
flatpak uninstall -y --user "$@"
|
|
1145
|
+
flatpak uninstall -y --user "$@" 2>/dev/null || run_as_root flatpak uninstall -y "$@"
|
|
1163
1146
|
;;
|
|
1164
1147
|
npm)
|
|
1165
1148
|
npm uninstall -g "$@"
|
|
1166
1149
|
;;
|
|
1167
1150
|
bun)
|
|
1168
|
-
bun remove --global "$@"
|
|
1151
|
+
bun remove --global "$@"
|
|
1169
1152
|
;;
|
|
1170
1153
|
esac
|
|
1171
1154
|
}
|
|
@@ -1257,13 +1240,13 @@ manager_update() {
|
|
|
1257
1240
|
run_as_root snap refresh
|
|
1258
1241
|
;;
|
|
1259
1242
|
flatpak)
|
|
1260
|
-
flatpak update -y --user
|
|
1243
|
+
flatpak update -y --user 2>/dev/null || run_as_root flatpak update -y
|
|
1261
1244
|
;;
|
|
1262
1245
|
npm)
|
|
1263
1246
|
npm update -g
|
|
1264
1247
|
;;
|
|
1265
1248
|
bun)
|
|
1266
|
-
bun update --global
|
|
1249
|
+
bun update --global
|
|
1267
1250
|
;;
|
|
1268
1251
|
esac
|
|
1269
1252
|
}
|
|
@@ -1303,14 +1286,16 @@ run_fuzzy_selector() {
|
|
|
1303
1286
|
--layout=reverse \
|
|
1304
1287
|
--marker='>>' \
|
|
1305
1288
|
--header="${header_line}" \
|
|
1306
|
-
--info=
|
|
1289
|
+
--info=inline-right \
|
|
1290
|
+
--ansi \
|
|
1307
1291
|
--margin="2%,1%,2%,1%" \
|
|
1308
1292
|
--cycle \
|
|
1293
|
+
--tiebreak=begin,chunk,length \
|
|
1309
1294
|
--bind=ctrl-k:preview:"cat ${KBINDS_FILE}" \
|
|
1310
1295
|
--bind=ctrl-h:preview:"cat ${HELP_FILE}" \
|
|
1311
1296
|
--bind='ctrl-/:change-preview-window(hidden|)' \
|
|
1312
1297
|
--bind=ctrl-n:next-selected,ctrl-b:prev-selected \
|
|
1313
|
-
--bind='focus:transform-preview-label:echo {1}
|
|
1298
|
+
--bind='focus:transform-preview-label:echo [{1}] {2}')
|
|
1314
1299
|
|
|
1315
1300
|
if [[ -n "${reload_cmd}" ]]; then
|
|
1316
1301
|
fzf_args+=(--disabled --bind="start:reload:${reload_cmd}" --bind="change:reload:${reload_cmd}")
|
|
@@ -1323,9 +1308,16 @@ run_fuzzy_selector() {
|
|
|
1323
1308
|
|
|
1324
1309
|
main() {
|
|
1325
1310
|
ensure_tmp_root
|
|
1311
|
+
initialize_session_tmp_root
|
|
1312
|
+
trap cleanup_session_tmp_root EXIT
|
|
1326
1313
|
|
|
1327
1314
|
parse_args "$@"
|
|
1328
1315
|
|
|
1316
|
+
if [[ "${ACTION}" == "version" ]]; then
|
|
1317
|
+
print_version
|
|
1318
|
+
exit 0
|
|
1319
|
+
fi
|
|
1320
|
+
|
|
1329
1321
|
local detected_manager
|
|
1330
1322
|
local detected_managers=()
|
|
1331
1323
|
while IFS= read -r detected_manager; do
|
|
@@ -1371,8 +1363,11 @@ main() {
|
|
|
1371
1363
|
local query
|
|
1372
1364
|
query="$(join_query)"
|
|
1373
1365
|
|
|
1374
|
-
if [[ "${ACTION}"
|
|
1366
|
+
if [[ "${ACTION}" != "feed-search" ]]; then
|
|
1375
1367
|
log "Using manager(s): ${manager_display}"
|
|
1368
|
+
fi
|
|
1369
|
+
|
|
1370
|
+
if [[ "${ACTION}" == "update" ]]; then
|
|
1376
1371
|
if confirm_action "Run update/upgrade for ${manager_display}?"; then
|
|
1377
1372
|
for manager in "${managers[@]-}"; do
|
|
1378
1373
|
log "Updating with $(manager_label "${manager}")"
|
|
@@ -1385,7 +1380,7 @@ main() {
|
|
|
1385
1380
|
fi
|
|
1386
1381
|
|
|
1387
1382
|
local display_file
|
|
1388
|
-
display_file="$(mktemp "${
|
|
1383
|
+
display_file="$(mktemp "${SESSION_TMP_ROOT}/display.XXXXXX")"
|
|
1389
1384
|
: >"${display_file}"
|
|
1390
1385
|
|
|
1391
1386
|
if [[ "${ACTION}" == "feed-search" ]]; then
|
|
@@ -1408,14 +1403,14 @@ main() {
|
|
|
1408
1403
|
local gather_pid
|
|
1409
1404
|
|
|
1410
1405
|
for manager in "${managers[@]-}"; do
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
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}" '
|
|
1419
1414
|
NF >= 1 {
|
|
1420
1415
|
desc = $2
|
|
1421
1416
|
if (desc == "") desc = "-"
|
|
@@ -1446,13 +1441,16 @@ main() {
|
|
|
1446
1441
|
|
|
1447
1442
|
if [[ ! -s "${display_file}" ]]; then
|
|
1448
1443
|
rm -f "${display_file}"
|
|
1449
|
-
|
|
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."
|
|
1450
1448
|
fi
|
|
1451
1449
|
|
|
1452
1450
|
local header
|
|
1453
1451
|
case "${ACTION}" in
|
|
1454
1452
|
search)
|
|
1455
|
-
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)"
|
|
1456
1454
|
;;
|
|
1457
1455
|
list)
|
|
1458
1456
|
header="Select installed package(s) to inspect from ${manager_display}"
|
|
@@ -1476,7 +1474,7 @@ main() {
|
|
|
1476
1474
|
rm -f "${display_file}"
|
|
1477
1475
|
|
|
1478
1476
|
if [[ -z "${selected}" ]]; then
|
|
1479
|
-
log "
|
|
1477
|
+
log "Selection canceled"
|
|
1480
1478
|
exit 0
|
|
1481
1479
|
fi
|
|
1482
1480
|
|
|
@@ -1494,7 +1492,7 @@ main() {
|
|
|
1494
1492
|
done <<<"${selected}"
|
|
1495
1493
|
|
|
1496
1494
|
if [[ "${#selected_packages[@]}" -eq 0 ]]; then
|
|
1497
|
-
log "
|
|
1495
|
+
log "Selection canceled"
|
|
1498
1496
|
exit 0
|
|
1499
1497
|
fi
|
|
1500
1498
|
|