#compdef ponymix local -a _commands _movesink local state line curcontext="$curcontext" typeset -U _commands _common_command(){ _commands+=( 'list:list available devices' 'list-short:list available devices, short form' 'list-cards:list available cards' 'list-cards-short:list available cards, short form' 'get-volume:get volume for device' 'set-volume:set volume for device:integer' 'get-balance:get balance for device' 'set-balance:set balance for device:integer' 'adj-balance:increase or decrease balance for device:integer' 'increase:increase volume:integer' 'decrease:decrease volume:integer' 'mute:mute device' 'kill:kill device' 'unmute:unmute device' 'toggle:toggle mute' 'is-muted:check if muted' ) cmd="${${_commands[(r)$words[$((CURRENT - 1))]:*]%%:*}}" if (( ! $#cmd )); then _describe commands _commands; else if (( $#cmd )) && [[ "$cmd" == set-* || "$cmd" == adj-* ]]; then _message "number for $cmd" else _message "no more options" fi fi } _devices(){ local -a _sourcelist _sinklist _inputlist for f in ${(f)"$(_call_program sink_tag "$service --sink list-short")"}; do _sinklist+=(${${(ps:\t:)f}[3]}:${(q)${(ps:\t:)f}[4]}) done for f in ${(f)"$(_call_program source_tag "$service --source list-short")"}; do _sourcelist+=(${${(ps:\t:)f}[3]}:${(q)${(ps:\t:)f}[4]}) done for f in ${(f)"$(_call_program sink_input_tag "$service --sink-input list-short")"}; do _inputlist+=(${${(ps:\t:)f}[2]}:${(q)${(ps:\t:)f}[4]}) done if [[ $words[(r)*sink-input*] == *sink-input ]]; then _describe "sink inputs" _inputlist elif [[ $words[(r)*(sink|output)*] == *(sink|output) ]]; then _describe "sink" _sinklist elif [[ $words[(r)*(source|input)*] == *(source|input) ]]; then _describe "source" _sourcelist else _alternative \ "source_tag:source list:((${(q)_sourcelist[@]}))" \ "sink_tag:sink:((${(q)_sinklist[@]}))" \ "sink_input_tag:sink_input:((${(q)_inputlist[@]}))" fi } _set_profiles(){ local -a _profileslist local _card _card=$words[$(($words[(i)-(c|-card)] + 1))] _profileslist=(${${(f)"$(_call_program profiles_tag "$service --card $_card list-profiles-short")"}//:/\:}) compadd "$@" - "$_profileslist[@]" } _cards(){ local -a _cardlist _cardlist=(${(f)"$(_call_program card_tag "$service list-cards-short")"}) _describe 'card list' _cardlist } _card_commands=( 'list-profiles:list available profiles for a card' 'list-profiles-short:list available profiles for a card, short form' 'get-profile:get active profile for card' 'set-profile:set profile for a card:_set_profiles' ) if [[ -n $words[(r)*(sink-input|source-output)] ]]; then _commands+=( 'move:Move device' ) fi [[ $words[(r)-(d|-device)] == -(d|-device) ]] && _commands+=( 'defaults:list default devices (default command)' 'set-default:set default devices') [[ $words[(r)-(c|-card)] == -(c|-card) ]] && _commands+=( "$_card_commands[@]" ) if [[ $words[$((CURRENT - 1))] == move ]]; then for f in ${(f)"$(_call_program sink_tag "$service --sink list-short")"}; do _movesink+=(${${(ps:\t:)f}[3]}:${(q)${(ps:\t:)f}[4]}) done _describe "sink" _movesink elif [[ $words[$((CURRENT - 1))] == set-profile ]]; then _set_profiles else _arguments -C \ '::common commands:_common_command' \ '(-c --card -d --device)'{-d,--device}'[Select Device]:devices:_devices' \ - '(help)' \ {-h,--help}'[display this help and exit]' \ - '(version)' \ {-V,--version}'[display program version and exit]' \ - '(sink)' \ '--sink[alias to type sink]' \ '--output[alias to type sink]' \ {-t,--devtype}'[Device Type]: :(sink output)' \ - '(source)' \ '--source[alias to type source]' \ '--input[alias to type source]' \ {-t,--devtype}'[Device Type]: :(source input)' \ - '(sink-input)' \ '--sink-input[alias to type sink-input]' \ {-t,--devtype}'[Device Type]: :(sink-input)' \ - '(source-output)' \ {-t,--devtype}'[Device Type]:device types:(source-output)' \ '--source-output[alias to type source-output]' \ - '(card)' \ '(-d --device)'{-c,--card}'[target card]:Cards:_cards:Card Commands:((${(q)_card_commands}))' fi #vim: set ft=zsh sw=4 ts=4 noet