aboutsummaryrefslogtreecommitdiff
path: root/files/.config/nnn/plugins/fzcd
diff options
context:
space:
mode:
Diffstat (limited to 'files/.config/nnn/plugins/fzcd')
-rwxr-xr-xfiles/.config/nnn/plugins/fzcd89
1 files changed, 89 insertions, 0 deletions
diff --git a/files/.config/nnn/plugins/fzcd b/files/.config/nnn/plugins/fzcd
new file mode 100755
index 0000000..125092c
--- /dev/null
+++ b/files/.config/nnn/plugins/fzcd
@@ -0,0 +1,89 @@
+#!/usr/bin/env sh
+
+# Description: Fuzzy search multiple locations read-in from a path-list file
+# (or $PWD) and open the selected file's dir in a smart context.
+# Dependencies: fzf, find (only for multi-location search)
+#
+# Details: Paths in list file should be newline-separated absolute paths.
+# Paths can be file paths; the script will scan the parent dirs.
+#
+# The path-list file precedence is:
+# - "$1" (the hovered file) if it exists, is plain-text and the
+# first line points to an existing file
+# - "$LIST" if set below
+# - "$2" (the current directory) [mimics plugin fzcd behaviour]
+#
+# The path-list file can be generated easily:
+# - pick the (file)paths in picker mode to path-list file
+# - OR, edit selection in nnn and save as path-list file
+#
+# Shell: POSIX compliant
+# Author: Anna Arad, Arun Prakash Jana, KlzXS
+
+IFS="$(printf '\n\r')"
+
+# shellcheck disable=SC1090,SC1091
+. "$(dirname "$0")"/.nnn-plugin-helper
+
+CTX=+
+LIST="${LIST:-""}"
+
+if ! type fzf >/dev/null 2>&1; then
+ printf "fzf missing"
+ read -r _
+ exit 1
+fi
+
+if [ -n "$1" ] && [ "$(file -b --mime-type "$1")" = 'text/plain' ] && [ -e "$(head -1 "$1")" ]; then
+ LIST="$1"
+elif ! [ -s "$LIST" ]; then
+ sel=$(fzf)
+ # Show only the file and parent dir
+ # sel=$(fzf --delimiter / --with-nth=-2,-1 --tiebreak=begin --info=hidden)
+
+ LIST=''
+fi
+
+if [ -n "$LIST" ]; then
+ if type find >/dev/null 2>&1; then
+ tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
+
+ while IFS= read -r path; do
+ if [ -d "$path" ]; then
+ printf "%s\n" "$path" >> "$tmpfile"
+ elif [ -f "$path" ]; then
+ printf "%s\n" "$(dirname "$path")" >> "$tmpfile"
+ fi
+ done < "$LIST"
+
+ sel=$(xargs -d '\n' < "$tmpfile" -I{} find {} -type f -printf "%H//%P\n" | sed '/.*\/\/\(\..*\|.*\/\..*\)/d; s:/\+:/:g' | fzf --delimiter / --tiebreak=begin --info=hidden)
+ # Alternative for 'fd'
+ # sel=$(xargs -d '\n' < "$tmpfile" fd . | fzf --delimiter / --tiebreak=begin --info=hidden)
+
+ rm "$tmpfile"
+ else
+ printf "find missing"
+ read -r _
+ exit 1
+ fi
+fi
+
+if [ -n "$sel" ]; then
+ if [ "$sel" = "." ] || { ! [ -d "$sel" ] && ! [ -f "$sel" ]; }; then
+ exit 0
+ fi
+
+ # Check if the selected path returned by fzf command is absolute
+ case $sel in
+ /*) nnn_cd "$sel" "$CTX" ;;
+ *)
+ # Remove "./" prefix if it exists
+ sel="${sel#./}"
+
+ if [ "$PWD" = "/" ]; then
+ nnn_cd "/$sel" "$CTX"
+ else
+ nnn_cd "$PWD/$sel" "$CTX"
+ fi;;
+ esac
+fi