diff options
Diffstat (limited to 'files/.config/nnn/plugins/fzcd')
| -rwxr-xr-x | files/.config/nnn/plugins/fzcd | 89 |
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 |
