diff --git a/plugins/extract/_extract b/plugins/extract/_extract
index 6641443d3..7d71aeb1b 100644
--- a/plugins/extract/_extract
+++ b/plugins/extract/_extract
@@ -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
diff --git a/plugins/extract/extract.plugin.zsh b/plugins/extract/extract.plugin.zsh
old mode 100644
new mode 100755
index aed77e7d7..8219f974e
--- a/plugins/extract/extract.plugin.zsh
+++ b/plugins/extract/extract.plugin.zsh
@@ -9,14 +9,41 @@ Usage: extract [-option] [file ...]
Options:
-r, --remove Remove archive after unpacking.
+ -t, --to-directory
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
@@ -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
@@ -126,7 +157,7 @@ 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, with :t it gives zsh
local tmp_name==(:); tmp_name="${tmp_name:t}"
command mv "${content[1]}" "$tmp_name" \
@@ -134,9 +165,9 @@ EOF
&& 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"