# bash completion for GNU tar -*- shell-script -*- _tar() { local cur prev words cword split _init_completion -s || return local ext regex tar untar if [[ $cword -eq 1 ]]; then COMPREPLY=( $( compgen -W 'c t x u r d A' -- "$cur" ) ) return 0 fi local tars='@(@(tar|gem|spkg)?(.@(Z|[bgx]z|bz2|lz?(ma)))|t@([abglx]z|b?(z)2))' case ${words[1]} in --*) ;; ?(-)*[cr]*f) if [[ $cword -eq 2 ]]; then ext='@(tar|gem|spkg)' case ${words[1]} in *a*) ext="$tars" ;; *z*) ext='t?(ar.)gz' ;; *Z*) ext='ta@(r.Z|z)' ;; *[jy]*) ext='t@(?(ar.)bz?(2)|b2)' ;; *J*) ext='t?(ar.)xz' ;; esac _filedir $ext else _filedir fi return 0 ;; +([^ZzJjy])f) ext="$tars" regex='\(\(tar\|gem\|spkg\)\(\.\(Z\|[bgx]z\|bz2\|lz\(ma\)\?\)\)\?\|t\([abglx]z\|bz\?2\)\)' ;; *[Zz]*f) ext='@(@(t?(ar.)|gem.|spkg.)@(gz|Z)|taz)' regex='\(\(t\(ar\.\)\?\|gem\.\|spkg\.\)\(gz\|Z\)\|taz\)' ;; *[jy]*f) ext='@(@(t?(ar.)|gem.)bz?(2)|spkg|tb2)' regex='\(\(t\(ar\.\)\?\|gem\.\)bz2\?\|spkg\|tb2\)' ;; *[J]*f) ext='@(@(tar|gem|spkg).@(lzma|xz)|t[lx]z)' regex='\(\(tar\|gem\|spkg\)\.\(lzma\|xz\)\|t[lx]z\)' ;; *) _filedir return 0 ;; esac case $prev in *${ext:-$tars}) # complete on files in tar file # # get name of tar file from command line tar=$( sed -e 's/^.* \([^ ]*'$regex'\) .*$/\1/' <<<"${words[@]}" ) # devise how to untar and list it untar=t${words[1]//[^Jzjyf]/} local IFS=$'\n' COMPREPLY=( $( compgen -W "$( printf '%s\n' $( tar $untar $tar \ 2>/dev/null ) )" -- "$cur" ) ) return 0 ;; -C|--directory) _filedir -d return 0 ;; --atime-preserve) COMPREPLY=( $( compgen -W 'replace system' -- "$cur" ) ) return 0 ;; --group) COMPREPLY=( $( compgen -g -- "$cur" ) ) return 0 ;; --owner) COMPREPLY=( $( compgen -u -- "$cur" ) ) return 0 ;; -F|--info-script|--new-volume-script|--rmt-command|--rsh-command|\ -I|--use-compress-program) compopt -o filenames COMPREPLY=( $( compgen -c -- "$cur" ) ) return 0 ;; --volno-file|--add-file|-T|--files-from|-X|--exclude-from|--index-file) _filedir return 0 ;; -H|--format) COMPREPLY=( $( compgen -W 'gnu oldgnu pax posix ustar v7' \ -- "$cur" ) ) return 0 ;; --quoting-style) COMPREPLY=( $( compgen -W 'literal shell shell-always c c-maybe escape locale clocale' -- "$cur" ) ) return 0 ;; --totals) COMPREPLY=( $( compgen -W 'SIGHUP SIGQUIT SIGINT SIGUSR1 SIGUSR2' \ -- "$cur" ) ) return 0 ;; --occurrence|--sparse-version|--to-command|--mode|--mtime|\ --tape-length|-b|--blocking-factor|--record-size|-V|--text|--backup|\ --exclude|--exclude-tag*|-K|--starting-file|-N|--newer|--after-date|\ --suffix|--strip-components|--transform|--xform|--checkpoint|\ --checkpoint-action|--no-quote-chars|--quote-chars|--warnings) return 0 ;; esac $split && return 0 # file completion on relevant files _filedir "$ext" return 0 } [ -n "${COMP_TAR_INTERNAL_PATHS:-}" ] && complete -F _tar -o dirnames tar || complete -F _tar tar # ex: ts=4 sw=4 et filetype=sh