Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/extract/_extract
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ local -a exts=(

_arguments \
'(-r --remove)'{-r,--remove}'[Remove archive.]' \
'(-t --to-directory)'{-t,--to-directory}'[Extract to a specific directory.]' \
"*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \
&& return 0
47 changes: 39 additions & 8 deletions plugins/extract/extract.plugin.zsh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,41 @@ Usage: extract [-option] [file ...]

Options:
-r, --remove Remove archive after unpacking.
-t, --to-directory <dir> Extract to a specific directory instead of the current one.
EOF
fi

local remove_archive=1
if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then
remove_archive=0
shift
fi
local target_directory=""

while (( $# > 0 )); do
case "$1" in
-r|--remove)
remove_archive=0
shift
;;
-t|--to-directory)
shift
if (( $# == 0 )); then
echo "extract: -t/--to-directory requires a directory argument" >&2
return 1
fi

target_directory="$1"
shift

if [[ ! -d "$target_directory" ]]; then
echo "extract: '$target_directory' is not a valid directory" >&2
return 1
fi

target_directory="${target_directory%/}"
;;
*)
break
;;
esac
done

local pwd="$PWD"
while (( $# > 0 )); do
Expand All @@ -35,6 +62,10 @@ EOF
extract_dir="${extract_dir:r}"
fi

if [[ -n "$target_directory" ]]; then
extract_dir="$target_directory/${extract_dir:t}"
fi

# If there's a file or directory with the same name as the archive
# add a random string to the end of the extract directory
if [[ -e "$extract_dir" ]]; then
Expand Down Expand Up @@ -126,17 +157,17 @@ EOF
# 1. Move and rename the extracted file/folder to a temporary random name
# 2. Delete the empty folder
# 3. Rename the extracted file/folder to the original name
if [[ "${content[1]:t}" == "$extract_dir" ]]; then
if [[ "${content[1]:t}" == "${extract_dir:t}" ]]; then
# =(:) gives /tmp/zsh<random>, with :t it gives zsh<random>
local tmp_name==(:); tmp_name="${tmp_name:t}"
command mv "${content[1]}" "$tmp_name" \
&& command rmdir "$extract_dir" \
&& command mv "$tmp_name" "$extract_dir"
# Otherwise, if the extracted folder name already exists in the current
# directory (because of a previous file / folder), keep the extract_dir
elif [[ ! -e "${content[1]:t}" ]]; then
command mv "${content[1]}" . \
&& command rmdir "$extract_dir"
elif [[ ! -e "${target_directory:-.}/${content[1]:t}" ]]; then
command mv -- "${content[1]}" "${target_directory:-.}/" \
&& command rmdir -- "$extract_dir"
fi
elif [[ ${#content} -eq 0 ]]; then
command rmdir "$extract_dir"
Expand Down