Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #!/usr/bin/env bash
  2. declare esc=$(printf '\033')
  3. declare c_reset="${esc}[0m"
  4. declare c_red="${esc}[31m"
  5. err() {
  6. echo -e "${c_red}$1${c_reset}" >&2
  7. }
  8. die() {
  9. exit 1
  10. }
  11. has() {
  12. local verbose=false
  13. if [[ $1 == '-v' ]]; then
  14. verbose=true
  15. shift
  16. fi
  17. for c in "$@"; do c="${c%% *}"
  18. if ! command -v "$c" &> /dev/null; then
  19. [[ "$verbose" == true ]] && err "$c not found"
  20. return 1
  21. fi
  22. done
  23. }
  24. has -v fzf || die
  25. fzf() {
  26. command fzf --cycle "$@"
  27. }
  28. pick_files() {
  29. local files fzpick
  30. mapfile -t files < <(find . -maxdepth 1 2> /dev/null | sort | sed '1d; s|^\./||')
  31. fzpick=$( for f in "${files[@]}"; do
  32. if [[ -d "$f" ]]; then
  33. printf '%s/\n' "$f"
  34. elif [[ -L "$f" ]]; then
  35. printf '%s@\n' "$f"
  36. else
  37. printf '%s\n' "$f"
  38. fi
  39. done | fzf --multi --header='move these files' ) || return 1
  40. for f in "${fzpick[@]}"; do
  41. realpath -s "$f"
  42. done
  43. }
  44. pick_destination() {
  45. local cwd browsedir browseinfo query dirs
  46. cwd=$(pwd)
  47. while [[ "$browsedir" != "$cwd" ]]; do
  48. dirs=$( (echo '..'; find -maxdepth 1 -type d 2> /dev/null ) |
  49. sed 's|./||' |
  50. sort)
  51. mapfile -t browseinfo < <(
  52. fzf --print-query \
  53. --history="${HOME}/.cache/fzmv_history" \
  54. --header="${errors:-move files here}" <<< "$dirs")
  55. query=${browseinfo[0]}
  56. browsedir=${browseinfo[1]}
  57. [[ -d "$query" ]] && browsedir="$query"
  58. [[ ! -d "$browsedir" ]] && return 1
  59. if [[ "$browsedir" == '.' && $(realpath "$browsedir") != "$cwd" ]]; then
  60. realpath "$browsedir"
  61. break
  62. else
  63. cd "$browsedir" || die
  64. continue
  65. fi
  66. done
  67. }
  68. while (( $# > 0 )); do
  69. case $1 in
  70. -t|--test) dryrun=true ;;
  71. esac
  72. shift
  73. done
  74. mapfile -t files < <(pick_files)
  75. (( ${#files[@]} > 0 )) || exit 1
  76. destination=$(pick_destination) || exit 1
  77. ${dryrun:+echo} mv -t "$destination" "${files[@]}"