@@ -203,10 +203,17 @@ _comp_cmd_tar__preparse_cmdline()
203203
204204 for i in " $@ " ; do
205205 case " $i " in
206- --delete | --test-label)
206+ --delete | --test-label | --catenate | --concatenate | --extract | --get | --update | --list | --append | --create )
207207 tar_mode=${i: 2: 100}
208- tar_mode_arg=$i
209- break
208+ ;;
209+ --bzip2 | --xz | --lzip | --lzma | --lzop | --zstd)
210+ tar_compression_mode=${i: 2: 100}
211+ ;;
212+ --gzip | --gunzip | --ungzip)
213+ tar_compression_mode=" gzip"
214+ ;;
215+ --compress | --uncompress)
216+ tar_compression_mode=" compress"
210217 ;;
211218 --* )
212219 # skip
@@ -236,7 +243,7 @@ _comp_cmd_tar__file_option()
236243 local ext=" $1 "
237244
238245 case " $tar_mode " in
239- c)
246+ c | create )
240247 # no need to advise user to re-write existing tarball
241248 _comp_compgen_filedir -d
242249 ;;
@@ -391,7 +398,7 @@ _comp_cmd_tar__adjust_PREV_from_old_option()
391398_comp_cmd_tar__extract_like_mode ()
392399{
393400 local i
394- for i in x d t delete; do
401+ for i in x d t delete extract get list ; do
395402 [[ $tar_mode == " $i " ]] && return 0
396403 done
397404 return 1
@@ -437,10 +444,15 @@ _comp_cmd_tar__cleanup_prev()
437444 fi
438445}
439446
447+ _comp_cmd_tar__is_bsdtar ()
448+ {
449+ [[ ${COMP_WORDS[0]} == ? (* /)bsdtar ]]
450+ }
451+
440452_comp_cmd_tar__detect_ext ()
441453{
442454 local tars=' @(@(tar|spkg)?(.@(Z|[bgx]z|bz2|lz?(ma|o)|zst))|t@([abglx]z|b?(z)2|zst)|cbt|gem|xbps)'
443- if [[ ${COMP_WORDS[0]} == ? ( * /)bsdtar ]] ; then
455+ if _comp_cmd_tar__is_bsdtar ; then
444456 # https://github.com/libarchive/libarchive/wiki/LibarchiveFormats
445457 tars=${tars/% \) / |pax|cpio|iso|zip|@ (j|x)ar|mtree|a|7z|warc}
446458 if _comp_cmd_tar__extract_like_mode; then
@@ -453,33 +465,44 @@ _comp_cmd_tar__detect_ext()
453465 fi
454466 ext=" $tars "
455467
456- case " $tar_mode_arg " in
457- --* )
458- # Should never happen?
459- ;;
460- ? (-)* [cr]* f)
468+ if ! _comp_cmd_tar__extract_like_mode; then
469+ if ! _comp_cmd_tar__is_bsdtar; then
461470 ext=' @(tar|gem|spkg|cbt|xpbs)'
462- case ${words[1]} in
463- * a* ) ext=" $tars " ;;
464- * z* ) ext=' t?(ar.)gz' ;;
465- * Z* ) ext=' ta@(r.Z|z)' ;;
466- * [jy]* ) ext=' t@(?(ar.)bz?(2)|b2)' ;;
467- * J* ) ext=' t?(ar.)xz' ;;
468- esac
469- ;;
470- + ([^ZzJjy])f)
471- # Pass through using defaults above
472- ;;
473- * [Zz]* f)
474- ext=' @(@(t?(ar.)|spkg.)@(gz|Z)|taz)'
475- ;;
476- * [jy]* f)
477- ext=' @(t?(ar.)bz?(2)|spkg|tb2)'
478- ;;
479- * [J]* f)
480- ext=' @(@(tar|spkg).@(lzma|xz)|t[lx]z)'
481- ;;
482- esac
471+ fi
472+ case $tar_mode_arg :$tar_compression_mode in
473+ * a* :none | * :auto-compress)
474+ ext=" $tars "
475+ ;;
476+ * z* :none | * :gzip)
477+ ext=' t?(ar.)gz'
478+ ;;
479+ * Z* :none | * :compress)
480+ ext=' ta@(r.Z|z)'
481+ ;;
482+ * [jy]* :none | * :bzip2)
483+ ext=' t@(?(ar.)bz?(2)|b2)'
484+ ;;
485+ * J* :none | * :xz)
486+ ext=' t?(ar.)xz'
487+ ;;
488+ esac
489+ else
490+ # TODO: lzip, lzma, lzop
491+ case $tar_mode_arg :$tar_compression_mode in
492+ * [Zz]* f:none | * :gzip | * :compress)
493+ ext=' @(@(t?(ar.)|spkg.)@(gz|Z)|taz)'
494+ ;;
495+ * [jy]* f:none | * :bzip2)
496+ ext=' @(t?(ar.)bz?(2)|spkg|tb2)'
497+ ;;
498+ * J* f:none | * :xz)
499+ ext=' @(@(tar|spkg).@(lzma|xz)|t[lx]z)'
500+ ;;
501+ * :zstd)
502+ ext=' t?(ar.)zst'
503+ ;;
504+ esac
505+ fi
483506}
484507
485508_comp_cmd_tar__gnu ()
@@ -490,13 +513,15 @@ _comp_cmd_tar__gnu()
490513 tar_mode tar_mode_arg old_opt_progress=" " \
491514 old_opt_used=" " old_opt_parsed=()
492515
493- # Main mode, e.g. -x or -c ( extract/creation)
516+ # Main mode, e.g. "x" or "c" or the long forms " extract" or "create"
494517 local tar_mode=none
495518
496519 # The mode argument, e.g. -cpf or -c
497- # FIXME: handle long options
498520 local tar_mode_arg=
499521
522+ # Compression mode - from long options
523+ local tar_compression_mode=none
524+
500525 if [[ -v _comp_cmd_tar__debug ]]; then
501526 set -x
502527 local PS4=' $BASH_SOURCE:$LINENO: '
@@ -681,12 +706,13 @@ _comp_cmd_tar__posix()
681706 # The mode argument, e.g. -cpf or -c
682707 local tar_mode_arg=
683708
709+ # Compression mode - from long options
710+ local tar_compression_mode=none
711+
684712 local cur prev words cword was_split comp_args
685713
686714 _comp_initialize -s -- " $@ " || return
687715
688- tar_mode=none
689-
690716 # relatively compatible modes are {c,t,x}
691717 # relatively compatible options {b,f,m,v,w}
692718 short_arg_req=" fb"
0 commit comments