aboutsummaryrefslogtreecommitdiffstats
path: root/bash-completion
blob: b9388c4d908805c5a6be16bff242ebee5bde9999 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/bin/bash

in_array() {
  local i
  for i in "${@:2}"; do
    [[ $1 = "$i" ]] && return
  done
}

_ponymix() {
  local flags='-h --help -c --card -d --device -t --devtype
               --source --input --sink --output
               --sink-input --source-output'
  local types='sink sink-input source source-output'
  local verbs=(help defaults set-default list list-short
               list-cards list-cards-short get-volume set-volume
               get-balance set-balance adj-balance increase decrease
               mute unmute toggle is-muted move kill
               list-profiles list-profiles-short get-profile set-profile)
  local i=0 cur prev verb word devtype dev idx devices

  _get_comp_words_by_ref cur prev

  for word in "${COMP_WORDS[@]}"; do
    # find the verb
    if in_array "$word" "${verbs[@]}"; then
      verb=$word
      break
    fi

    case $word in
      --devtype|-t)
        # look ahead to next word
        if [[ ${COMP_WORDS[i+1]} ]]; then
          devtype=${COMP_WORDS[i+1]}
        fi
        ;;
      --devtype=*)
        devtype=${word#--devtype=}
        ;;
      -t*)
        devtype=${word#-t}
        ;;
      --sink|--output)
        devtype=sink
        ;;
      --source|--input)
        devtype=source
        ;;
      --sink-input|--source-output)
        devtype=${word#--}
        ;;
    esac
    (( ++i ))
  done

  case $prev in
    --card|-c)
      mapfile -t cards < <(\ponymix list-cards-short 2>/dev/null)
      local IFS=$'\n'
      COMPREPLY=($(compgen -W '$(printf "%s\n" "${cards[@]//\ /\\ }")' -- "$cur"))
      ;;
    --device|-d)
      while IFS=$'\t' read _ dev idx _; do
        devices+=("$dev" "$idx")
      done < <(\ponymix "--${devtype:-sink}" list-short 2>/dev/null)
      local IFS=$'\n'
      COMPREPLY=($(compgen -W '$(printf "%s\n" "${devices[@]//\ /\\ }")' -- "$cur"))
      ;;
    --devtype|-t)
      COMPREPLY=($(compgen -W '$types' -- "$cur"))
      ;;
  esac
  [[ $COMPREPLY ]] && return 0

  case $cur in
    -*)
      COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur"))
      ;;
    *)
      [[ -z $verb ]] && COMPREPLY=($(compgen -W '${verbs[*]}' -- "$cur"))
      ;;
  esac
  [[ $COMPREPLY ]] && return 0

  case $word in
    '')
      COMPREPLY=($(compgen -W '${verbs[*]}' -- "$cur"))
      ;;
  esac
  [[ $COMPREPLY ]] && return 0

  case $verb in
    move)
      if [[ $devtype = sink?(-input) ]]; then
        while IFS=$'\t' read _ dev idx _; do
          devices+=("$dev" "$idx")
        done < <(\ponymix --sink list-short 2>/dev/null)
      elif [[ $devtype = source?(-output) ]]; then
        while IFS=$'\t' read _ dev idx _; do
          devices+=("$dev" "$idx")
        done < <(\ponymix --source list-short 2>/dev/null)
      fi
      if [[ $devices ]]; then
        local IFS=$'\n'
        COMPREPLY=($(compgen -W '$(printf "%s\n" "${devices[@]//\ /\\ }")' -- "$cur"))
      fi
      ;;
  esac

  return 0
}

complete -F _ponymix ponymix

# vim: set et ts=2 sw=2: