fzcd (2694B)
1 #!/usr/bin/env sh 2 3 # Description: Fuzzy search multiple locations read-in from a path-list file 4 # (or $PWD) and open the selected file's dir in a smart context. 5 # Dependencies: fzf, find (only for multi-location search) 6 # 7 # Details: Paths in list file should be newline-separated absolute paths. 8 # Paths can be file paths; the script will scan the parent dirs. 9 # 10 # The path-list file precedence is: 11 # - "$1" (the hovered file) if it exists, is plain-text and the 12 # first line points to an existing file 13 # - "$LIST" if set below 14 # - "$2" (the current directory) [mimics plugin fzcd behaviour] 15 # 16 # The path-list file can be generated easily: 17 # - pick the (file)paths in picker mode to path-list file 18 # - OR, edit selection in nnn and save as path-list file 19 # 20 # Shell: POSIX compliant 21 # Author: Anna Arad, Arun Prakash Jana, KlzXS 22 23 IFS="$(printf '\n\r')" 24 25 # shellcheck disable=SC1090,SC1091 26 . "$(dirname "$0")"/.nnn-plugin-helper 27 28 CTX=+ 29 LIST="${LIST:-""}" 30 31 if ! type fzf >/dev/null 2>&1; then 32 printf "fzf missing" 33 read -r _ 34 exit 1 35 fi 36 37 if [ -n "$1" ] && [ "$(file -b --mime-type "$1")" = 'text/plain' ] && [ -e "$(head -1 "$1")" ]; then 38 LIST="$1" 39 elif ! [ -s "$LIST" ]; then 40 sel=$(fzf) 41 # Show only the file and parent dir 42 # sel=$(fzf --delimiter / --with-nth=-2,-1 --tiebreak=begin --info=hidden) 43 44 LIST='' 45 fi 46 47 if [ -n "$LIST" ]; then 48 if type find >/dev/null 2>&1; then 49 tmpfile=$(mktemp /tmp/abc-script.XXXXXX) 50 51 while IFS= read -r path; do 52 if [ -d "$path" ]; then 53 printf "%s\n" "$path" >> "$tmpfile" 54 elif [ -f "$path" ]; then 55 printf "%s\n" "$(dirname "$path")" >> "$tmpfile" 56 fi 57 done < "$LIST" 58 59 sel=$(xargs -d '\n' < "$tmpfile" -I{} find {} -type f -printf "%H//%P\n" | sed '/.*\/\/\(\..*\|.*\/\..*\)/d; s:/\+:/:g' | fzf --delimiter / --tiebreak=begin --info=hidden) 60 # Alternative for 'fd' 61 # sel=$(xargs -d '\n' < "$tmpfile" fd . | fzf --delimiter / --tiebreak=begin --info=hidden) 62 63 rm "$tmpfile" 64 else 65 printf "find missing" 66 read -r _ 67 exit 1 68 fi 69 fi 70 71 if [ -n "$sel" ]; then 72 if [ "$sel" = "." ] || { ! [ -d "$sel" ] && ! [ -f "$sel" ]; }; then 73 exit 0 74 fi 75 76 # Check if the selected path returned by fzf command is absolute 77 case $sel in 78 /*) nnn_cd "$sel" "$CTX" ;; 79 *) 80 # Remove "./" prefix if it exists 81 sel="${sel#./}" 82 83 if [ "$PWD" = "/" ]; then 84 nnn_cd "/$sel" "$CTX" 85 else 86 nnn_cd "$PWD/$sel" "$CTX" 87 fi;; 88 esac 89 fi