sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

fzcd (2653B)


      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 . "$(dirname "$0")"/.nnn-plugin-helper
     26 
     27 CTX=+
     28 LIST="$LIST"
     29 
     30 if ! type fzf >/dev/null 2>&1; then
     31     printf "fzf missing"
     32     read -r _
     33     exit 1
     34 fi
     35 
     36 if [ -n "$1" ] && [ "$(file -b --mime-type "$1")" = 'text/plain' ] && [ -e "$(head -1 "$1")" ]; then
     37     LIST="$1"
     38 elif ! [ -s "$LIST" ]; then
     39     sel=$(fzf)
     40     # Show only the file and parent dir
     41     # sel=$(fzf --delimiter / --with-nth=-2,-1 --tiebreak=begin --info=hidden)
     42 
     43     LIST=''
     44 fi
     45 
     46 if [ -n "$LIST" ]; then
     47     if type find >/dev/null 2>&1; then
     48         tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
     49 
     50         while IFS= read -r path; do
     51             if [ -d "$path" ]; then
     52                 printf "%s\n" "$path" >> "$tmpfile"
     53             elif [ -f "$path" ]; then
     54                 printf "%s\n" "$(dirname "$path")" >> "$tmpfile"
     55             fi
     56         done < "$LIST"
     57 
     58         sel=$(xargs -d '\n' < "$tmpfile" -I{} find {} -type f -printf "%H//%P\n" | sed '/.*\/\/\(\..*\|.*\/\..*\)/d; s:/\+:/:g' | fzf --delimiter / --tiebreak=begin --info=hidden)
     59         # Alternative for 'fd'
     60         # sel=$(xargs -d '\n' < "$tmpfile" fd . | fzf --delimiter / --tiebreak=begin --info=hidden)
     61 
     62         rm "$tmpfile"
     63     else
     64         printf "find missing"
     65         read -r _
     66             exit 1
     67     fi
     68 fi
     69 
     70 if [ -n "$sel" ]; then
     71     if [ "$sel" = "." ] || { ! [ -d "$sel" ] && ! [ -f "$sel" ]; }; then
     72         exit 0
     73     fi
     74 
     75     # Check if the selected path returned by fzf command is absolute
     76     case $sel in
     77     /*) nnn_cd "$sel" "$CTX" ;;
     78     *)
     79         # Remove "./" prefix if it exists
     80         sel="${sel#./}"
     81 
     82         if [ "$PWD" = "/" ]; then
     83             nnn_cd "/$sel" "$CTX"
     84         else
     85             nnn_cd "$PWD/$sel" "$CTX"
     86         fi;;
     87     esac
     88 fi