summaryrefslogtreecommitdiff
path: root/completions/tar
diff options
context:
space:
mode:
authorGabriel F. T. Gomes <gabriel@inconstante.eti.br>2017-09-25 23:46:54 -0300
committerGabriel F. T. Gomes <gabriel@inconstante.eti.br>2017-09-25 23:46:54 -0300
commit6d88f1055806932d9291f96847d2b691cccda2cd (patch)
tree0ff79eedaa8a239331256048981deedbd0721965 /completions/tar
parent059a87a5936cfebfd2d71ab8057002cafb2ea051 (diff)
downloadbash-completion-6d88f1055806932d9291f96847d2b691cccda2cd.tar.gz
New upstream version 2.7upstream/2.7
Diffstat (limited to 'completions/tar')
-rw-r--r--completions/tar777
1 files changed, 688 insertions, 89 deletions
diff --git a/completions/tar b/completions/tar
index 374e0692..5a854edd 100644
--- a/completions/tar
+++ b/completions/tar
@@ -1,37 +1,455 @@
# bash completion for GNU tar -*- shell-script -*-
+#
+# General info
+# ============
+#
+# The "old" style arguments
+# -------------------------
+#
+# We don't "advice" the old tar option format by default for GNU tar, example:
+#
+# 'tar czfT /tmp/archive.tar patterns.txt'
+#
+# We rather advice the 'tar -czf /tmp/archive.tar -T patterns.txt' format of
+# arguments. Though, if user starts the 'first' tar argument without leading
+# dash, we treat the command line apropriately.
+#
+#
+# long/short options origin
+# -------------------------
+#
+# For GNU tar, everything is parsed from `tar --help` output so not so much
+# per-distribution work should be needed. The _parse_help does not seem to be
+# good enough so parsed here directly.
+#
+#
+# FIXME: --starting-file (-K) (should be matched for extraction only)
+# FIXME: handle already used (at least short) options
+# FIXME: Test-cases for make check.
+# - check for no global variable pollution
+# FIXME: why PS4='$BASH_SOURCE:$LINENO: ' shows sometimes negative lines?
+# FIXME: timeout on tarball listing
+# FIXME: cache 'tar --help' parsing results into global variables
+# FIXME: at least 'tar -<tab>' should show some helping text (apart from just
+# pure option advices)
+# FIXME: short option completion should be more intuitive
+# - verbose mode option should be advised multiple times
+# - mode option should be advised only once
+# - format option should be advised only once
+# ...
-_tar()
+__gtar_parse_help_opt()
{
- local cur prev words cword split
- _init_completion -s || return
+ local opttype arg opt separator optvar
+ opttype=long
+ arg="$2"
+ opt="$1"
+ separator=" "
- local ext regex tar untar
+ case "$opt" in
+ --*)
+ ;;
+ -\?)
+ return ;;
+ -*)
+ opttype=short
+ opt=${opt##-}
+ separator=
+ ;;
+ *)
+ echo >&2 "not an option $opt"
+ return 1
+ ;;
+ esac
+
+ # Remove arguments.
+ opt=${opt//\[*/}
+ opt=${opt//=*/=}
+
+ # Basic sanity.
+ opt=${opt//\"*/}
+ opt=${opt//\'*/}
+ opt=${opt//\;*/}
+
+ optvar=$opttype'_arg_'$arg
+
+ eval "$optvar=\"\$$optvar$separator\"\"$opt\""
+}
- if [[ $cword -eq 1 ]]; then
- COMPREPLY=( $( compgen -W 'c t x u r d A' -- "$cur" ) )
+
+__gtar_parse_help_line()
+{
+ local i
+
+ for i in $1; do
+ case "$i" in
+ # regular options
+ --*|-*)
+ __gtar_parse_help_opt "$i" "$2"
+ ;;
+
+ # end once there is single non-option word
+ *)
+ break
+ esac
+ done
+}
+
+
+__gnu_tar_parse_help()
+{
+ local str line arg
+ while IFS= read line; do
+ # Ok, this requires some comment probably. The GNU help output prints
+ # options on lines beginning with spaces. After that, there is one
+ # or more options separated by ', ' separator string. We are matching
+ # like this then: ^<spaces>(<separator>?<option>)+<whatever>$
+ if [[ "$line" =~ \
+ ^[[:blank:]]{1,10}(((,[[:blank:]])?(--?([\]\[a-zA-Z0-9?=-]+))(,[[:space:]])?)+).*$ ]]; then
+
+ line=${BASH_REMATCH[1]}
+ str="${line//,/ }"
+
+ # Detect that all options on this line accept arguments (and whether
+ # the arguments are required or not). Note that only long option
+ # description in GNU help output mentions arguments. So the $line
+ # variable may contain e.g. '-X, --XXX[=NAME], -XXX2[=NAME]'.
+ arg=none
+ if [[ "$line" =~ --[A-Za-z0-9-]+(\[?)= ]]; then
+ [[ -n "${BASH_REMATCH[1]}" ]] && arg=opt || arg=req
+ fi
+
+ __gtar_parse_help_line "$str" "$arg"
+ fi
+ done <<<"$(tar --help)"
+
+ long_opts="\
+ $long_arg_none\
+ $long_arg_opt\
+ $long_arg_req"
+
+ short_opts="$short_arg_none$short_arg_opt$short_arg_req"
+}
+
+
+# Hack: parse --warning keywords from tar's error output
+__gtar_parse_warnings()
+{
+ local line
+ while IFS= read line; do
+ if [[ $line =~ ^[[:blank:]]*-[[:blank:]]*[\`\']([a-zA-Z0-9-]+)\'$ ]]; then
+ echo "${BASH_REMATCH[1]} no-${BASH_REMATCH[1]}"
+ fi
+ done <<<"$(LC_ALL=C tar --warning= 2>&1)"
+}
+
+
+# Helper to obtain last character of string.
+__tar_last_char()
+{
+ echo "${1: $(( ${#1} - 1))}"
+}
+
+
+__tar_parse_old_opt()
+{
+ local first_word char
+
+ # current word is the first word
+ [[ "$cword" -eq 1 && -n "$cur" && "${cur:0:1}" != '-' ]] \
+ && old_opt_progress=1
+
+ # check that first argument does not begin with "-"
+ first_word=${words[1]}
+ [[ -n "$first_word" && "${first_word:0:1}" != "-" ]] \
+ && old_opt_used=1
+
+ # parse the old option (if present) contents to allow later code expect
+ # corresponding arguments
+ if [[ $old_opt_used -eq 1 ]]; then
+ char=${first_word:0:1}
+ while [[ -n "$char" ]]; do
+ if __tar_is_argreq "$char"; then
+ old_opt_parsed+=("$char")
+ fi
+ first_word=${first_word##$char}
+ char=${first_word:0:1}
+ done
+ fi
+}
+
+
+# Make the analysis of whole command line.
+__tar_preparse_cmdline()
+{
+ local first_arg my_args tmparg i modes="ctxurdA"
+
+ shift # progname
+
+ __tar_parse_old_opt
+
+ first_arg=1
+ for i in "$@"; do
+ case "$i" in
+ --delete|--test-label)
+ tar_mode=${i:2:100}
+ tar_mode_arg=$i
+ break
+ ;;
+ --*)
+ # skip
+ ;;
+ -*[$modes]*)
+ tar_mode=${i//[^$modes]/}
+ tar_mode=${tar_mode:0:1}
+ tar_mode_arg=$i
+ break
+ ;;
+ *[$modes]*)
+ # Only the first arg may be "MODE" without leading dash
+ if [[ $first_arg -eq 1 ]]; then
+ tar_mode=${i//[^$modes]/}
+ tar_mode=${tar_mode:0:1}
+ tar_mode_arg=$i
+ fi
+ ;;
+ esac
+ first_arg=0
+ done
+}
+
+
+# Generate completions for -f/--file.
+__tar_file_option()
+{
+ local ext="$1"
+
+ case "$tar_mode" in
+ c)
+ # no need to advise user to re-write existing tarball
+ _filedir -d
+ ;;
+ *)
+ _filedir "$ext"
+ ;;
+ esac
+}
+
+
+# Returns truth if option requires argument. No equal sign must be pasted.
+# Accepts option in format: 'c', '-c', '--create'
+__tar_is_argreq()
+{
+ local opt
+ opt=$1
+ case "$opt" in
+ -[A-Za-z0-9?])
+ [[ "$short_arg_req" =~ ${opt##-} ]] && return 0
+ ;;
+ [A-Za-z0-9?])
+ [[ "$short_arg_req" =~ ${opt} ]] && return 0
+ ;;
+ --*)
+ [[ "$long_arg_req" =~ [[:blank:]]$opt=[[:blank:]] ]] && return 0
+ ;;
+ esac
+
+ return 1
+}
+
+
+# Called only for short parameter
+__tar_complete_mode()
+{
+ local short_modes has_mode rawopt generated \
+ allshort_raw_unused allshort_raw \
+ filler i
+
+ short_modes="ctx"
+ [[ -z "$basic_tar" ]] && short_modes="ctxurdA"
+
+ # Remove prefix when needed
+ rawopt=${cur#-}
+
+ # -c -z -x ... => czx
+ allshort_raw=${short_opts//[- ]/}
+
+ # init the 'mode' option if no option is in ${cur}
+ if [[ "$tar_mode" == none ]]; then
+
+ # when user passed something like 'tar cf' do not put the '-' before
+ filler=
+ if [[ -z "$cur" && -z "$basic_tar" ]]; then
+ filler=-
+ fi
+
+ generated=""
+ for (( i=0 ; 1; i++ )); do
+ local c="${short_modes:$i:1}"
+ [[ -z "$c" ]] && break
+ generated+=" $filler$cur$c"
+ done
+
+ COMPREPLY=( $(compgen -W "$generated" ) )
return 0
fi
+ # The last short option requires argument, like '-cf<TAB>'. Cut the
+ # completion here to enforce argument processing.
+ if [[ "$old_opt_progress" -eq 0 ]] \
+ && __tar_is_argreq "$(__tar_last_char "$cur")"; then
+ COMPREPLY=( "$cur" ) && return 0
+ fi
+
+ allshort_raw_unused=${allshort_raw//[$rawopt]/}
+ if [[ "$tar_mode" != none ]]; then
+ allshort_raw_unused=${allshort_raw_unused//[$short_modes]}
+ fi
+
+ generated=
+ for (( i=0 ; 1; i++ )); do
+ local c="${allshort_raw_unused:$i:1}"
+ [[ -z "$c" ]] && break
+ generated+=" $cur$c"
+ done
+
+ COMPREPLY=( $( compgen -W "$generated" ) )
+
+ return 0
+}
+
+
+__gtar_complete_lopts()
+{
+ local rv
+ COMPREPLY=( $( compgen -W "$long_opts" -- "$cur" ) )
+ rv=$?
+ [[ $COMPREPLY == *= ]] && compopt -o nospace
+ return $rv
+}
+
+
+__gtar_complete_sopts()
+{
+ local generated short_mode_opts i c
+ short_mode_opts="ctxurdA"
+ generated=${short_opts//[$short_mode_opts]/}
+
+ for (( i=0 ; 1; i++ )); do
+ c="${allshort_raw_unused:$i:1}"
+ [[ -z "$c" ]] && break
+ generated+=" $cur$c"
+ done
+
+ COMPREPLY=( $( compgen -W "$generated" -- "$cur" ) )
+}
+
+
+__tar_try_mode()
+{
+ case "$cur" in
+ --*)
+ # posix tar does not support long opts
+ [[ -n "$basic_tar" ]] && return 0
+ __gtar_complete_lopts
+ return $?
+ ;;
+
+ -*)
+ # posix tar does not support short optios
+ [[ -n "$basic_tar" ]] && return 0
+
+ __tar_complete_mode && return 0
+ ;;
+
+ *)
+ if [[ "$cword" -eq 1 || "$tar_mode" == none ]]; then
+ __tar_complete_mode && return 0
+ fi
+ ;;
+ esac
+ return 1
+}
+
+
+__tar_adjust_PREV_from_old_option()
+{
+ # deal with old style arguments here
+ # $ tar cfTC # expects this sequence of arguments:
+ # $ tar cfTC ARCHIVE_FILE PATTERNS_FILE CHANGE_DIR
+ if [[ "$old_opt_used" -eq 1 && "$cword" -gt 1 \
+ && "$cword" -lt $(( ${#old_opt_parsed[@]} + 2 )) ]];
+ then
+ # make e.g. 'C' option from 'cffCT'
+ prev="-${old_opt_parsed[ $cword - 2 ]}"
+ fi
+}
+
+
+__tar_extract_like_mode()
+{
+ local i
+ for i in x d t delete; do
+ [[ "$tar_mode" == "$i" ]] && return 0
+ done
+ return 1
+}
+
+
+__tar_try_list_archive()
+{
+ local tarball tarbin untar
+
+ __tar_extract_like_mode || return 1
+
+ # This all is just to approach directory completion from "virtual"
+ # directory structure in tarball (for which the _filedir is unusable)
+
+ set -- "${words[@]}"
+ tarbin=$1
+ untar="tf"
+ shift
+
+ read tarball <<<"$(printf -- '%s\n' "$@" \
+ | command sed -n "/^.\{1,\}$regex\$/p")"
+ if [[ -n "$tarball" ]]; then
+ local IFS=$'\n'
+ COMPREPLY=($(compgen -o filenames -W "$(
+ while read line; do
+ printf "%q\n" "$(printf %q"\n" "$line")"
+ done <<<"$($tarbin $untar "$tarball" 2>/dev/null)"
+ )" -- "$(printf "%q\n" "$cur")"))
+ return 0
+ fi
+}
+
+__tar_cleanup_prev()
+{
+ if [[ "$prev" =~ ^-[a-zA-Z0-9?]*$ ]]; then
+ # transformate '-caf' ~> '-f'
+ prev="-$(__tar_last_char "$prev")"
+ fi
+}
+
+__tar_detect_ext()
+{
local tars='@(@(tar|gem|spkg)?(.@(Z|[bgx]z|bz2|lz?(ma)))|t@([abglx]z|b?(z)2))'
+ ext="$tars"
+ regex='\(\(tar\|gem\|spkg\)\(\.\(Z\|[bgx]z\|bz2\|lz\(ma\)\?\)\)\?\|t\([abglx]z\|bz\?2\)\)'
- case ${words[1]} in
+ case "$tar_mode_arg" in
--*)
+ # Should never happen?
;;
?(-)*[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
+ 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
;;
+([^ZzJjy])f)
ext="$tars"
@@ -49,84 +467,265 @@ _tar()
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)
+
+_gtar()
+{
+ local long_opts short_opts \
+ long_arg_none long_arg_opt long_arg_req \
+ short_arg_none short_arg_opt short_arg_req \
+ tar_mode tar_mode_arg old_opt_progress=0 \
+ old_opt_used=0 old_opt_parsed=()
+
+ # Main mode, e.g. -x or -c (extract/creation)
+ local tar_mode=none
+
+ # The mode argument, e.g. -cpf or -c
+ # FIXME: handle long options
+ local tar_mode_arg=
+
+ if [[ "$_TAR_OPT_DEBUG" == 1 ]]; then
+ set -x
+ PS4="\$BASH_SOURCE:\$LINENO: "
+ fi
+
+ local cur prev words cword split
+
+ _init_completion -s || return
+
+ # Fill the {long,short}_{opts,arg*}
+ __gnu_tar_parse_help
+
+ __tar_preparse_cmdline "${words[@]}"
+
+ local ext regex tar untar
+
+ __tar_detect_ext
+
+ while true; do # just-for-easy-break while, not looping
+ __tar_adjust_PREV_from_old_option
+ __tar_posix_prev_handle && break
+ __tar_cleanup_prev
+
+ # Handle all options *REQUIRING* argument. Optional arguments are up to
+ # user (TODO: is there any sane way to deal with this?). This case
+ # statement successes only if there already is PREV.
+ case $prev in
+ -C|--directory)
+ _filedir -d
+ break
+ ;;
+ --atime-preserve)
+ COMPREPLY=( $( compgen -W 'replace system' -- "$cur" ) )
+ break
+ ;;
+ --group)
+ COMPREPLY=( $( compgen -g -- "$cur" ) )
+ break
+ ;;
+ --owner)
+ COMPREPLY=( $( compgen -u -- "$cur" ) )
+ break
+ ;;
+ -F|--info-script|--new-volume-script|--rmt-command|--rsh-command|\
+ -I|--use-compress-program)
+ compopt -o filenames
+ COMPREPLY=( $( compgen -c -- "$cur" ) )
+ break
+ ;;
+ --volno-file|--add-file|-T|--files-from|-X|--exclude-from|\
+ --index-file|--listed-incremental|-g)
+ _filedir
+ break
+ ;;
+ -H|--format)
+ COMPREPLY=( $( compgen -W 'gnu oldgnu pax posix ustar v7' \
+ -- "$cur" ) )
+ break
+ ;;
+ --quoting-style)
+ COMPREPLY=( $( compgen -W 'literal shell shell-always c c-maybe
+ escape locale clocale' -- "$cur" ) )
+ break
+ ;;
+ --totals)
+ COMPREPLY=( $( compgen -W 'SIGHUP SIGQUIT SIGINT SIGUSR1 SIGUSR2' \
+ -- "$cur" ) )
+ break
+ ;;
+ --warning)
+ COMPREPLY=( $( compgen -W "$(__gtar_parse_warnings)" -- "$cur" ) )
+ break
+ ;;
+ --file|-f|-!(-*)f)
+ __tar_file_option "$ext"
+ break
+ ;;
+ --*)
+ # parameter with required argument but no completion yet
+ [[ " $long_arg_req " =~ \ $prev=\ ]] && break
+
+ # parameter with optional argument passed with =, something like
+ # --occurrence=*<TAB> which is not handled above
+ [[ " $long_arg_opt " =~ \ $prev\ ]] && break
+
+ # if there is some unknown option with '=', for example
+ # (literally) user does --nonexistent=<TAB>, we do not want
+ # continue also
+ $split && break
+
+ # Most probably, when code goes here, the PREV variable contains
+ # some string from "$long_arg_none" and we want continue.
+ ;;
+ -[a-zA-Z0-9?])
+ # argument required but no completion yet
+ [[ "$short_arg_req" =~ ${prev##-} ]] && break
+ ;;
+ esac
+
+ # safety belts
+ case "$cur" in
+ -[a-zA-Z0-9]=*)
+ # e.g. 'tar -c -f=sth' does not what user could expect
+ break
+ ;;
+ esac
+
+ # Handle the main operational mode of tar. We should do it as soon as
+ # possible.
+ __tar_try_mode && break
+
+ # handle others
+ case "$cur" in
+ --*)
+ __gtar_complete_lopts
+ break
+ ;;
+ -*)
+ # called only if it is *not* first parameter
+ __gtar_complete_sopts
+ break
+ ;;
+ esac
+
+ # the first argument must be "mode" argument or --param, if any of those
+ # was truth - the 'break' statement would have been already called
+ [[ "$cword" -eq 1 ]] && break
+
+ __tar_try_list_archive && break
+
+ # file completion on relevant files
+ if [[ $tar_mode != none ]]; then
_filedir
+ fi
+
+ break
+ done # just-for-easy-break while
+
+ if [[ "$_TAR_OPT_DEBUG" == 1 ]]; then
+ set +x
+ unset PS4
+ fi
+}
+
+
+__tar_posix_prev_handle()
+{
+ case "$prev" in
+ -f)
+ __tar_file_option "$ext"
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)
+ -b)
return 0
- ;;
esac
- $split && return 0
+ return 1
+}
+
+
+_posix_tar()
+{
+ local long_opts short_opts basic_tar \
+ long_arg_none long_arg_opt long_arg_req \
+ short_arg_none short_arg_opt short_arg_req \
+ tar_mode tar_mode_arg old_opt_progress=0 \
+ old_opt_used=1 old_opt_parsed=()
+
+ # Main mode, e.g. -x or -c (extract/creation)
+ local tar_mode=none
+
+ # The mode argument, e.g. -cpf or -c
+ local tar_mode_arg=
+
+ local cur prev words cword split
+
+ _init_completion -s || return
+
+ basic_tar=yes
+ tar_mode=none
+
+ # relatively compatible modes are {c,t,x}
+ # relatively compatible options {b,f,m,v,w}
+ short_arg_req="fb"
+ short_arg_none="wmv"
+ short_opts="$short_arg_req$short_arg_none"
+
+ __tar_preparse_cmdline "${words[@]}"
+
+ local ext regex tar untar
+
+ __tar_detect_ext
+
+ __tar_adjust_PREV_from_old_option
+
+ __tar_posix_prev_handle && return
+
+ __tar_try_mode && return
+
+ __tar_try_list_archive && return
# file completion on relevant files
- _filedir "$ext"
+ _filedir
+}
- return 0
+
+_tar()
+{
+ local cmd=${COMP_WORDS[0]} func line
+ read line <<<"$($cmd --version 2>/dev/null)"
+ case "$line" in
+ *GNU*)
+ func=_gtar
+ ;;
+ *)
+ func=_posix_tar
+ ;;
+ esac
+ $func "$@"
+
+ # Install real completion for subsequent completions
+ if [ -n "${COMP_TAR_INTERNAL_PATHS:-}" ]; then
+ complete -F $func -o dirnames tar
+ else
+ complete -F $func tar
+ fi
+ unset -f _tar
}
-[ -n "${COMP_TAR_INTERNAL_PATHS:-}" ] && complete -F _tar -o dirnames tar ||
- complete -F _tar tar
-# ex: ts=4 sw=4 et filetype=sh
+
+if [ -n "${COMP_TAR_INTERNAL_PATHS:-}" ]; then
+ complete -F _tar -o dirnames tar
+ complete -F _gtar -o dirnames gtar
+ complete -F _posix_tar -o dirnames bsdtar
+ complete -F _posix_tar -o dirnames star
+else
+ complete -F _tar tar
+ complete -F _gtar gtar
+ complete -F _posix_tar bsdtar
+ complete -F _posix_tar star
+fi
+
+# ex: filetype=sh