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"