# 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 -' should show some helping text (apart from just # pure option advices) # FIXME: short option completion should be more intuitive # - verbose mode option should be adviced multiple times # - mode option should be adviced only once # - format option should be adviced only once # ... __gtar_parse_help_opt() { local opttype arg opt separator optvar opttype=long arg="$2" opt="$1" separator=" " 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\"" } __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: ^(?