#compdef truncate local curcontext=$curcontext variant rs ret=1 local -a state state_descr line specs optA typeset -A opt_args _pick_variant -r variant gnu=GNU $OSTYPE --version [[ $variant != gnu ]] && rs='-r -s' # -r/-s mutually exclusive # common specs specs=( '(hv -c --no-create)'{-c,--no-create}'[do not create any files]' "(hv $rs -r --reference)"{-r+,--reference=}'[base size on the specified file]:reference file:_files' "(hv $rs -s --size)"{-s+,--size=}'[set or adjust the file size by specified bytes]:size:->size' '(hv)*: :_files' ) case $variant in gnu) # GNU coreutils 8.32 specs+=( '(hv -o --io-blocks)'{-o,--io-blocks}'[treat the specified size as number of IO blocks instead of bytes]' + 'hv' '(- *)--help[display help and exit]' '(- *)--version[output version information and exit]' ) ;; *) # FreeBSD/DragonFly specs=( ${specs:#(|*\))--*} ) # remove long options optA=( -A '-*' ) ;; esac _arguments -C -s -S : $specs && ret=0 case $state in size) local unit=bytes (( ${#opt_args[(I)(-o|--io-blocks)]} )) && unit=blocks local -a suffix=( K:1024 M G T ) local -a prefix=( '+:extend by' '-:reduce by' ) local prefix_char='[-+]' case $variant in gnu|freebsd*) prefix+=( '/:round down to multiple of' '%:round up to multiple of' ) ;| gnu) suffix=( K:1024 KB:1000 {M,G,T,P,E,Z,Y}{,B} ) prefix+=( '<:at most' '>:at least' ) prefix_char='([-+/%]|\\[<>])' ;; freebsd*) prefix_char='[-+/%]' ;; esac local -a numbers=( _numbers -u $unit size $suffix ) if compset -P "$prefix_char"; then $numbers && ret=0 elif (( ${#opt_args[(I)(-r|--reference)]} )); then # prefix is required if the reference file is given _describe -t 'prefixes' 'prefix' prefix && ret=0 else _alternative "prefixes:prefix:((${(@q)prefix}))" \ "sizes: :$numbers" && ret=0 fi ;; esac return ret