My build of nnn with minor changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

137 line
2.8 KiB

  1. #!/usr/bin/env bash
  2. # Description: An almost fully POSIX compliant batch file renamer
  3. #
  4. # Note: nnn auto-detects and invokes this plugin if available
  5. #
  6. # Capabilities:
  7. # 1. Basic file rename
  8. # 2. Detects order change
  9. # 3. Can move files
  10. # 4. Can remove files
  11. # 5. Switch number pairs to swap filenames
  12. #
  13. # Shell: bash
  14. # Author: KlzXS
  15. EDITOR="${EDITOR:-vi}"
  16. TMPDIR="${TMPDIR:-/tmp}"
  17. INCLUDE_HIDDEN="${INCLUDE_HIDDEN:-0}"
  18. selection=${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection
  19. exit_status=0
  20. dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
  21. if [ -s "$selection" ]; then
  22. printf "Rename 'c'urrent / 's'election? "
  23. read -r resp
  24. fi
  25. if [ "$resp" = "s" ]; then
  26. arr=$(tr '\0' '\n' < "$selection")
  27. else
  28. if [ "$INCLUDE_HIDDEN" -eq 0 ]; then
  29. arr=$(find . ! -name . -prune ! -name ".*" -print | sort)
  30. else
  31. arr=$(find . ! -name . -prune -print | sort)
  32. fi
  33. fi
  34. printf "%s" "$arr" | awk '{print NR " " $0}' > "$dst_file"
  35. items=("~")
  36. while IFS='' read -r line; do
  37. items+=("$line");
  38. done < <(printf "%s\n" "$arr")
  39. $EDITOR "$dst_file"
  40. while read -r num name; do
  41. if [ -z "$name" ]; then
  42. if [ -z "$num" ]; then
  43. continue
  44. fi
  45. printf "%s: unable to parse line, aborting\n" "$0"
  46. exit 1
  47. fi
  48. # check if $num is an integer
  49. if [ ! "$num" -eq "$num" ] 2> /dev/null; then
  50. printf "%s: unable to parse line, aborting\n" "$0"
  51. exit 1
  52. fi
  53. src=${items[$num]}
  54. if [ -z "$src" ]; then
  55. printf "%s: unknown item number %s\n" "$0" "$num" > /dev/stderr
  56. continue
  57. elif [ "$name" != "$src" ]; then
  58. if [ -z "$name" ]; then
  59. continue
  60. fi
  61. if [ ! -e "$src" ] && [ ! -L "$src" ]; then
  62. printf "%s: %s does not exit\n" "$0" "$src" > /dev/stderr
  63. unset "items[$num]"
  64. continue
  65. fi
  66. # handle swaps
  67. if [ -e "$name" ] || [ -L "$name" ]; then
  68. tmp="$name~"
  69. c=0
  70. while [ -e "$tmp" ] || [ -L "$tmp" ]; do
  71. c=$((c+1))
  72. tmp="$tmp~$c"
  73. done
  74. if mv "$name" "$tmp"; then
  75. printf "'%s' -> '%s'\n" "$name" "$tmp"
  76. else
  77. printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
  78. exit_status=1
  79. fi
  80. for key in "${!items[@]}"; do
  81. if [ "${items[$key]}" = "$name" ]; then
  82. items[$key]="$tmp"
  83. fi
  84. done
  85. fi
  86. dir=$(dirname "$name")
  87. if [ ! -d "$dir" ] && ! mkdir -p "$dir"; then
  88. printf "%s: failed to create directory tree %s\n" "$0" "$dir" > /dev/stderr
  89. exit_status=1
  90. elif ! mv "$src" "$name"; then
  91. printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
  92. exit_status=1
  93. else
  94. if [ -d "$name" ]; then
  95. for key in "${!items[@]}"; do
  96. items[$key]=$(printf "%s" "${items[$key]}" | sed "s|^$src\(\$\|\/\)|$name\1|")
  97. done
  98. printf "'%s' => '%s'\n" "$src" "$name"
  99. else
  100. printf "'%s' -> '%s'\n" "$src" "$name"
  101. fi
  102. fi
  103. fi
  104. unset "items[$num]"
  105. done <"$dst_file"
  106. unset "items[0]"
  107. for item in "${items[@]}"; do
  108. rm -ri "$item"
  109. done
  110. rm "$dst_file"
  111. exit $exit_status