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