# 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 # ... proc __gtar_parse_help_opt { local opttype arg opt separator optvar setvar opttype = 'long' setvar arg = "$2" setvar opt = "$1" setvar separator = "" "" case (opt) { --* { } -\? { return } -* { setvar opttype = 'short' setvar opt = ${opt##-} setvar separator = '' } * { echo >&2 "not an option $opt>&2 "not an option $opt" return 1 } } # Remove arguments. setvar opt = ${opt//\[*/} setvar opt = ${opt//=*/=} # Basic sanity. setvar opt = ${opt//\"*/} setvar opt = ${opt//\'*/} setvar opt = ${opt//\;*/} setvar optvar = "$opttype'_arg_'$arg" eval "$optvar=\"\$$optvar$separator\"\"$opt\"" } proc __gtar_parse_help_line { local i for i in $1 { case (i) { # regular options --*|-* { __gtar_parse_help_opt $i $2 } # end once there is single non-option word * { break; } } } } proc __gnu_tar_parse_help { local str line arg'' while IFS= read line { # 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: ^(?