Nelze vybrat více než 25 témat
Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
92 lines
1.9 KiB
92 lines
1.9 KiB
#!/usr/bin/env bash |
|
|
|
declare -r esc=$'\033' |
|
declare -r c_reset="${esc}[0m" |
|
declare -r c_red="${esc}[31m" |
|
declare dryrun verbose |
|
|
|
set -e |
|
|
|
err() { |
|
printf "${c_red}%s${c_reset}\n" "$*" >&2 |
|
} |
|
|
|
die() { |
|
exit 1 |
|
} |
|
|
|
has() { |
|
local verbose=0 |
|
if [[ $1 == '-v' ]]; then |
|
verbose=1 |
|
shift |
|
fi |
|
for c; do c="${c%% *}" |
|
if ! command -v "$c" &> /dev/null; then |
|
(( verbose > 0 )) && err "$c not found" |
|
return 1 |
|
fi |
|
done |
|
} |
|
|
|
has -v fzf || die |
|
|
|
fzf() { |
|
command fzf --cycle "$@" |
|
} |
|
|
|
pick_files() { |
|
local files fzpick |
|
find . -maxdepth 1 2> /dev/null | |
|
sort -h | |
|
sed '1d; s|^\./||' | |
|
while read -r f; do |
|
if [[ -d "$f" ]]; then |
|
printf '%s/\n' "$f" |
|
elif [[ -L "$f" ]]; then |
|
printf '%s@\n' "$f" |
|
else |
|
printf '%s\n' "$f" |
|
fi |
|
done | |
|
fzf --multi --header='move these files' || return 1 |
|
} |
|
|
|
pick_destination() { |
|
local cwd browse_dir browse_info query dirs |
|
cwd=$(pwd) |
|
while [[ "$browse_dir" != "$cwd" ]]; do |
|
mapfile -t browse_info < <( |
|
{ echo '..'; find . -maxdepth 1 -type d 2> /dev/null; } | |
|
sed 's|^./||' | |
|
sort -h | |
|
fzf --print-query \ |
|
--history="${HOME}/.cache/fzmv_history" \ |
|
--header="${errors:-move files here}") |
|
query=${browse_info[0]} |
|
browse_dir=${browse_info[1]} |
|
files=( "${browse_info[@]:2}" ) |
|
[[ -d "$query" ]] && browse_dir="$query" |
|
[[ ! -d "$browse_dir" ]] && return 1 |
|
if [[ "$browse_dir" == '.' && $(realpath "$browse_dir") != "$cwd" ]]; then |
|
realpath "$browse_dir" |
|
break |
|
else |
|
cd "$browse_dir" || die |
|
continue |
|
fi |
|
done |
|
} |
|
|
|
while (( $# > 0 )); do |
|
case $1 in |
|
-t|--test) dryrun=true ;; |
|
-v|--verbose) verbose=1 ;; |
|
esac |
|
shift |
|
done |
|
|
|
mapfile -t files < <(pick_files) |
|
(( ${#files[@]} > 0 )) || exit 1 |
|
destination=$(pick_destination) || exit 1 |
|
${dryrun:+echo} mv ${verbose:+-v} -t "$destination" "${files[@]}"
|
|
|