diff --git a/completions/7z b/completions/7z index a4b086c0..56e37a6d 100644 --- a/completions/7z +++ b/completions/7z @@ -10,14 +10,49 @@ _7z() return fi + local mode + [[ ${words[1]} == @(a|d|u) ]] && mode=w || mode=r + case $cur in - -mhe=*) + -ao*) + COMPREPLY=( $( compgen -P${cur:0:3} -W 'a s t u' -- "${cur:3}" ) ) + return + ;; + -?(a)[ix]*) + local opt + if [[ $cur == -a[ix]* ]]; then + opt=${cur:0:3} cur=${cur:3} + else + opt=${cur:0:2} cur=${cur:2} + fi + if [[ $cur != *[@\!]* ]]; then + COMPREPLY=( $( compgen -P$opt -W '@ ! r@ r-@ r0@ r! r-! r0!' \ + -- "$cur" ) ) + elif [[ $cur == ?(r@(-|0|))@* ]]; then + local x tmp + x=$( compgen -P"${opt}${cur%%@*}@" -f -- "${cur#*@}" ) && + while read -r tmp; do + COMPREPLY+=( "$tmp" ) + done <<< "$x" + compopt -o filenames + fi + return + ;; + -mhe=*|-mhc=*|-ms=*|-mt=*) COMPREPLY=( $( compgen -W 'on off' -- "${cur#*=}" ) ) return ;; + -mx=*) + COMPREPLY=( $( compgen -W '0 1 3 5 7 9' -- "${cur#*=}" ) ) + return + ;; -o*|-w?*) + local x tmp + x=$( compgen -P${cur:0:2} -S/ -d -- "${cur:2}" ) && + while read -r tmp; do + COMPREPLY+=( "$tmp" ) + done <<< "$x" compopt -o nospace -o filenames - COMPREPLY=( $( compgen -P${cur:0:2} -S/ -d -- "${cur:2}" ) ) return ;; -r?*) @@ -34,19 +69,29 @@ _7z() return ;; -t*) - COMPREPLY=( $( compgen -P${cur:0:2} -W '7z zip gzip bzip2 tar' \ - -- "${cur:2}" ) ) + if [[ $mode == w ]]; then + COMPREPLY=( $( compgen -P${cur:0:2} -W '7z bzip2 gzip swfc + tar wim xz zip' -- "${cur:2}" ) ) + else + COMPREPLY=( $( compgen -P${cur:0:2} -W '7z apm arj bzip2 cab + chm cpio cramfs deb dmg elf fat flv gzip hfs iso lzh lzma + lzma86 macho mbr mslz mub nsis ntfs pe ppmd rar rpm + squashfs swf swfc tar udf vhd wim xar xz z zip' \ + -- "${cur:2}" ) ) + fi return ;; - -a*|-i*|-m*|-p*|-u*|-v*|-x*) + -m*=*|-p*|-u*|-v*) return ;; esac if [[ $cur == -* ]]; then - COMPREPLY=( $( compgen -W '-ai -ax -bd -i -m -o -p -r -scs -sfx -si - -slt -so -ssc -t -u -v -w -x -y' -- "$cur" ) ) - [[ $COMPREPLY == -@(bd|sfx|si|slt|so|ssc|[rwy]) ]] || compopt -o nospace + COMPREPLY=( $( compgen -W '-ai -an -ao -ax -bd -i -m{x,s,f,he,hc,mt}= + -o -p -r -scs -sfx -si -slp -slt -so -ssc -t -u -v -w -x -y' \ + -- "$cur" ) ) + [[ $COMPREPLY == -@(an|bd|sfx|si|slt|so|ssc|[rwy]) ]] || + compopt -o nospace return fi @@ -54,9 +99,19 @@ _7z() _count_args = if [[ $args -eq 2 ]]; then _filedir_xspec unzip - _filedir '@(7z|arj|bz2|cab|cpio|deb|gem|?(g)tar|?(t)[bg]z|tb?(z)2|rpm)' + [[ $mode == w ]] && + _filedir '@(7z|bz2|swf|?(g)tar|?(t)[bglx]z|tb?(z)2|wim)' || + _filedir '@(7z|arj|bz2|cab|chm|cpio|deb|dmg|flv|gem|img|iso|lz[ah]|lzma?(86)|pmd|[rx]ar|rpm|sw[fm]|?(g)tar|taz|?(t)[bglx]z|tb?(z)2|vhd|wim|Z)' else - _filedir + if [[ ${words[1]} == d ]]; then + local IFS=$'\n' + COMPREPLY=( $( compgen -W "$( printf '%s\n' $( 7z l ${words[2]} \ + -slt 2>/dev/null | sed -n '/^Path =/s/^Path = \(.*\)$/\1/p' \ + 2>/dev/null | tail -n+2 ) )" -- "$cur" ) ) + compopt -o filenames + else + _filedir + fi fi } && complete -F _7z 7z 7za diff --git a/test/fixtures/7z/a.7z b/test/fixtures/7z/a.7z new file mode 100644 index 00000000..33570649 Binary files /dev/null and b/test/fixtures/7z/a.7z differ diff --git a/test/fixtures/7z/f.txt b/test/fixtures/7z/f.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/test/fixtures/7z/f.txt @@ -0,0 +1 @@ + diff --git a/test/lib/completions/7z.exp b/test/lib/completions/7z.exp index 08d6bf12..4e7e8689 100644 --- a/test/lib/completions/7z.exp +++ b/test/lib/completions/7z.exp @@ -4,7 +4,7 @@ proc setup {} { proc teardown {} { - assert_env_unmodified + assert_env_unmodified {/OLDPWD=/d} } @@ -15,4 +15,23 @@ assert_complete_any "7z " sync_after_int +assert_complete "-tzip" "7z a ar -tzi" +sync_after_int + + +set dir $::srcdir/fixtures/_filedir +assert_complete_dir "-wa\\ b/" "7z x -wa\\ " $dir "" -nospace +sync_after_int + + +set dir $::srcdir/fixtures/7z +assert_complete_dir "a.7z" "7z x " $dir +sync_after_int + + +set dir $::srcdir/fixtures/7z +assert_complete_dir "abc" "7z d a.7z " $dir +sync_after_int + + teardown