Skip to content

Commit 0518a21

Browse files
yedayakakinomyoga
andcommitted
feat(tar): use long option compression options
Previously we only used single letter options to decide what file extensions to complete for extracting archives, make it also consider long options (gnu style). Co-Authored-By: Koichi Murase <[email protected]>
1 parent ba15cd0 commit 0518a21

File tree

2 files changed

+63
-32
lines changed

2 files changed

+63
-32
lines changed

completions/tar

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,15 @@ _comp_cmd_tar__preparse_cmdline()
205205
case "$i" in
206206
--delete | --test-label | --catenate | --concatenate | --extract | --get | --update | --list | --append | --create)
207207
tar_mode=${i:2:100}
208-
# FIXME: We don't set $tar_mode_arg since it's used for combined
209-
# single letter options, but that means we don't handle
210-
# compression formats.
211-
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"
212217
;;
213218
--*)
214219
# skip
@@ -439,10 +444,15 @@ _comp_cmd_tar__cleanup_prev()
439444
fi
440445
}
441446

447+
_comp_cmd_tar__is_bsdtar()
448+
{
449+
[[ ${COMP_WORDS[0]} == ?(*/)bsdtar ]]
450+
}
451+
442452
_comp_cmd_tar__detect_ext()
443453
{
444454
local tars='@(@(tar|spkg)?(.@(Z|[bgx]z|bz2|lz?(ma|o)|zst))|t@([abglx]z|b?(z)2|zst)|cbt|gem|xbps)'
445-
if [[ ${COMP_WORDS[0]} == ?(*/)bsdtar ]]; then
455+
if _comp_cmd_tar__is_bsdtar; then
446456
# https://github.com/libarchive/libarchive/wiki/LibarchiveFormats
447457
tars=${tars/%\)/|pax|cpio|iso|zip|@(j|x)ar|mtree|a|7z|warc}
448458
if _comp_cmd_tar__extract_like_mode; then
@@ -455,33 +465,44 @@ _comp_cmd_tar__detect_ext()
455465
fi
456466
ext="$tars"
457467

458-
case "$tar_mode_arg" in
459-
--*)
460-
# FIXME: get correct extensions for long options (gnu style)
461-
;;
462-
?(-)*[cr]*f)
468+
if ! _comp_cmd_tar__extract_like_mode; then
469+
if ! _comp_cmd_tar__is_bsdtar; then
463470
ext='@(tar|gem|spkg|cbt|xpbs)'
464-
case ${words[1]} in
465-
*a*) ext="$tars" ;;
466-
*z*) ext='t?(ar.)gz' ;;
467-
*Z*) ext='ta@(r.Z|z)' ;;
468-
*[jy]*) ext='t@(?(ar.)bz?(2)|b2)' ;;
469-
*J*) ext='t?(ar.)xz' ;;
470-
esac
471-
;;
472-
+([^ZzJjy])f)
473-
# Pass through using defaults above
474-
;;
475-
*[Zz]*f)
476-
ext='@(@(t?(ar.)|spkg.)@(gz|Z)|taz)'
477-
;;
478-
*[jy]*f)
479-
ext='@(t?(ar.)bz?(2)|spkg|tb2)'
480-
;;
481-
*[J]*f)
482-
ext='@(@(tar|spkg).@(lzma|xz)|t[lx]z)'
483-
;;
484-
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
485506
}
486507

487508
_comp_cmd_tar__gnu()
@@ -496,9 +517,11 @@ _comp_cmd_tar__gnu()
496517
local tar_mode=none
497518

498519
# The mode argument, e.g. -cpf or -c
499-
# FIXME: handle long options
500520
local tar_mode_arg=
501521

522+
# Compression mode - from long options
523+
local tar_compression_mode=none
524+
502525
if [[ -v _comp_cmd_tar__debug ]]; then
503526
set -x
504527
local PS4='$BASH_SOURCE:$LINENO: '
@@ -683,6 +706,9 @@ _comp_cmd_tar__posix()
683706
# The mode argument, e.g. -cpf or -c
684707
local tar_mode_arg=
685708

709+
# Compression mode - from long options
710+
local tar_compression_mode=none
711+
686712
local cur prev words cword was_split comp_args
687713

688714
_comp_initialize -s -- "$@" || return

test/t/test_tar.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,9 @@ def test_23(self, completion):
127127
def test_24(self, completion):
128128
assert completion == "archive.tar.xz dir/ dir2/".split()
129129

130+
# Test compression detection of gnu style options
131+
@pytest.mark.complete("tar --extract --xz --file ", cwd="tar")
132+
def test_25(self, completion):
133+
assert completion == "archive.tar.xz dir/ dir2/".split()
134+
130135
# TODO: "tar tf escape.tar a/b"

0 commit comments

Comments
 (0)