# 7z(1) completion -*- shell-script -*- _7z() { local cur prev words cword _init_completion -n = || return if ((cword == 1)); then COMPREPLY=($(compgen -W 'a b d e l t u x' -- "$cur")) return fi local mode [[ ${words[1]} == [adu] ]] && mode=w || mode=r case $cur in -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 IFS=$' \t\n' reset=$(shopt -po noglob) set -o noglob COMPREPLY=($(compgen -P"${opt}${cur%%@*}@" -f -- "${cur#*@}")) $reset 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 reset=$(shopt -po noglob) set -o noglob compopt -o filenames local ifs=$IFS IFS=$'\n' COMPREPLY=($(compgen -d -P${cur:0:2} -S/ -- "${cur:2}")) IFS=$ifs $reset compopt -o nospace return ;; -r?*) COMPREPLY=($(compgen -P${cur:0:2} -W '- 0' -- "${cur:2}")) return ;; -scs*) COMPREPLY=($(compgen -P${cur:0:4} -W 'UTF-8 WIN DOS' \ -- "${cur:4}")) return ;; -ssc?*) COMPREPLY=($(compgen -P${cur:0:4} -W '-' -- "${cur:4}")) return ;; -t*) 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 ;; -m*=* | -p* | -u* | -v*) return ;; esac if [[ $cur == -* ]]; then 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 local args _count_args = if ((args == 2)); then _filedir_xspec unzip # TODO: parsing 7z i output? # - how to figure out if the format is input or output? # - find string Formats:, read until next empty line # - extensions start from column 26 # - ignore everything in parens # - terminate on two spaces # - terminate on token containing anything [^a-z0-9] # (assumption: extensions are all lowercase) [[ $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)|msi|pmd|[rx]ar|rpm|sw[fm]|?(g)tar|taz|?(t)[bglx]z|tb?(z)2|vhd|wim|Z)' else if [[ ${words[1]} == d ]]; then local IFS=$'\n' COMPREPLY=($(compgen -W "$(printf '%s\n' "$($1 l ${words[2]} \ -slt 2>/dev/null | command 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 # ex: filetype=sh