about summary refs log tree commit diff
path: root/Completion/Unix/Command/_mpc
blob: fee5e06f4fb377d5ed41f4ca8f68d7e1c0cc5bd3 (plain) (blame)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#compdef mpc -value-,MPD_HOST,-default

local OUT foo MPD_MUSIC_DIR MPC_PLAYLIST_MATCHER MPC_FORMAT_STRING

# set this style to whatever --format string you want to use when
# constructing the list of playlist entries
zstyle -s ":completion:${curcontext}:*" mpc-format-string MPC_FORMAT_STRING
foo=(--format "${(q)MPC_FORMAT_STRING:-%file%}")

# set this style to the music_directory of mpd to get _files based completion
# for commands like "add"
zstyle -s ":completion:${curcontext}:" mpd-music-directory MPD_MUSIC_DIR

# matcher used for playlist completion
zstyle -s ":completion:${curcontext}:" mpd-playlist-matcher \
  MPC_PLAYLIST_MATCHER
: ${MPC_PLAYLIST_MATCHER:='m:{a-z}={A-Z} l:|=**'}

# this one is used to configure the behaviour of _mpc_helper_songnumbers,
# see _pids for the original
zstyle -s ":completion:${curcontext}:song-numbers" insert-song-numbers \
  OUT || OUT=single

_mpc_command() {
  local mpc_cmds

  mpc_cmds=(
    add:"append a song to the end of the current playlist"
    cdprev:"compact disk player-like previous command"
    channels:"list the channels that other clients have subscribed to"
    clear:"clear the current playlist"
    clearerror:"clear the current error"
    crop:"remove all songs except for the currently playing song"
    current:"show the currently playing song"
    crossfade:"set and display crossfade settings"
    del:"remove a song from the current playlist"
    disable:"disable an output"
    enable:"enable an output"
    toggleoutput:"toggle an output"
    idle:"wait until an event occurs"
    idleloop:"loop waiting for events"
    insert:"insert a song after the currently playing song in the playlist"
    listall:"list all songs in the music directory"
    load:"load file as a playlist"
    ls:"list the contents of specified directory"
    lsplaylists:"list currently available playlists"
    mixrampdb:"set and display mixrampdb settings"
    mixramdelay:"set and display mixrampdelay settings"
    move:"move song in playlist"
    next:"play the next song in the current playlist"
    outputs:"show the current outputs"
    pause:"pause the currently playing song"
    play:"start playing"
    playlist:"print the current playlist"
    prev:"play the previous song in the current playlist"
    random:"toggle random mode, or specify state"
    repeat:"toggle repeat mode, or specify state"
    single:"toggle single mode, or specify state"
    consume:"toggle consume mode, or specify state"
    replaygain:"set or display the replay gain mode"
    rm:"remove a playlist"
    save:"save a playlist to file"
    search:"search for a song"
    searchadd:"search songs and add them to the current playlist"
    searchplay:"search and play songs from the current playlist"
    find:"search for a song, exact match"
    findadd:"find songs and add them to the current playlist"
    list:"list all tags of given type"
    seek:"seek to the position specified in percent"
    shuffle:"shuffle the current playlist"
    stats:"display statistics about MPD"
    stop:"stop the currently playing playlists"
    toggle:"toggles Play/Pause, plays if stopped"
    update:"scan music directory for updates"
    version:"report version of MPD"
    volume:"set volume"
    status:"display MPD status"
    sendmessage:"send a message to the specified channel"
    waitmessage:"wait for at least one message on the specified channel"
    subscribe:"subscribe to the specified channel and continuously receive messages"
    sticker:"sticker management"
  )

  if (( CURRENT == 1 )); then
    _describe -t commands "mpc command" mpc_cmds || \
        _wanted commands expl "mpc command" compadd loadtab tab lstab
  else
    local cmd=$words[1]
    local curcontext="${curcontext%:*:*}:mpc-${cmd}:" ret=1
    if ! _call_function ret _mpc_$cmd; then
      _default && ret=0
    fi
    return ret
  fi
}

_mpc_helper_bool() {
  local expl states
  states=(on off yes no 1 0 true false)
  _wanted states expl boolean compadd -a states
}

(( $+functions[_mpc_helper_songnumbers] )) ||
_mpc_helper_songnumbers() {
  local out sn list expl MATCH desc all NM ret=1

  _tags song-numbers || return 1

  if [[ "$PREFIX" = [0-9]# ]]; then
    all=()
    MATCH="*${(Q)PREFIX}[0-9]#*"
  else
    all=(-U)
    MATCH="(#i)*${(Q)PREFIX}*"
    NM="$compstate[nmatches]"
  fi

  out=("${(@f)$(_call_program song-numbers $mpccmd $foo playlist)}")
  out=("${(@M)out[@]:#${~MATCH}}")

  sn=("${(@)${(@M)out}//(#b)(#s)(\#|[ >]#)([0-9]#)*/$match[2]}")
  list=("${(@Mr:COLUMNS-1:)out}")

  _wanted -V song-numbers expl 'song number' \
      compadd "$@" -ld list "$all[@]" -a sn && ret=0

  if [[ -n "$all" ]]; then
    case "$OUT" in
      menu)
        compstate[insert]=menu
        ;;
      single)
        [[ $compstate[nmatches] -ne NM+1 ]] &&
        compstate[insert]=
        ;;
      *)
        [[ ${#:-$PREFIX} -gt ${#compstate[unambiguous]} ]] &&
        compstate[insert]=menu
        ;;
    esac
  fi

  return ret
}

(( $+functions[_mpc_helper_playlists] )) ||
_mpc_helper_playlists() {
  local list expl
  list=(${(f)"$(_call_program playlists $mpccmd lsplaylists)"})
  _wanted playlists expl playlist compadd -M $MPC_PLAYLIST_MATCHER $expl -a list
}

(( $+functions[_mpc_helper_files] )) ||
_mpc_helper_files() {
  if [[ -n $MPD_MUSIC_DIR ]]; then
    _files -W $MPD_MUSIC_DIR
    return
  fi

  local -U list expl prefix=$PREFIX
  if [[ $words[CURRENT] != */* ]]; then
    list=( ${${(f)"$(_call_program files $mpccmd listall)"}%%/*})
    _wanted files expl file compadd -qS/ -a list
  else
    [[ $compstate[quote] = [\'\"] ]] && prefix="$compstate[quote]$PREFIX$compstate[quote]"
    list=(${(f)"$($mpccmd tab -- ${(Q)prefix} 2>/dev/null)"})
    _wanted files expl file _multi_parts / list
  fi
}

(( $+functions[_mpc_helper_directories] )) ||
_mpc_helper_directories() {
  if [[ -n $MPD_MUSIC_DIR ]]; then
    _files -/ -W $MPD_MUSIC_DIR
    return
  fi

  local -U list expl prefix=$PREFIX
  if [[ $words[CURRENT] != */* ]]; then
    list=( ${${(M)${(f)"$(_call_program directories $mpccmd listall)"}:#*/*}%%/*})
    _wanted directories expl directory compadd -qS/ -a list
  else
    [[ $compstate[quote] = [\'\"] ]] && prefix="$compstate[quote]$PREFIX$compstate[quote]"
    list=(${(f)"$($mpccmd lstab -- ${(Q)prefix} 2>/dev/null)"})
    _wanted directories expl directory _multi_parts / list
  fi
}

(( $+functions[_mpc_helper_outputs] )) ||
_mpc_helper_outputs() {
  local vals outline
  vals=(${${${${(M)${(f)"$(_call_program outputs $mpccmd outputs)"}:#Output * \(*\) is (en|dis)abled}##Output }%%\) is (en|dis)abled}/ \(/:})
  _describe -t outputs output vals
}

_mpc_add() {
  _mpc_helper_files
}

_mpc_del() {
  _mpc_helper_songnumbers
}

_mpc_play() {
  _mpc_helper_songnumbers
}

_mpc_seek() {
  _message "floating point percent value"
}

_mpc_enable() {
  _mpc_helper_outputs
}

_mpc_disable() {
  _mpc_helper_outputs
}

_mpc_toggleoutput() {
  _mpc_helper_outputs
}

_mpc_move() {
  if (( $#words <= 3 )); then
    _mpc_helper_songnumbers
  else
    _message "nothing"
  fi
}

_mpc_listall() {
  _mpc_helper_files
}

_mpc_ls() {
  _mpc_helper_directories
}

_mpc_lstab() {
  _mpc_helper_directories
}

_mpc_load() {
  _mpc_helper_playlists
}

_mpc_loadtab() {
  _mpc_helper_playlists
}

_mpc_save() {
  _mpc_helper_playlists
}

_mpc_tab() {
  _mpc_helper_files
}

_mpc_rm() {
  _mpc_helper_playlists
}

_mpc_volume() {
  local expl value="${${$(_call_program volume $mpccmd volume)#*:}%\%}" ret=1
  if [[ -prefix \+ && $value -lt 100 ]]; then
    _wanted -V volume expl volume compadd $expl - +{1..$((100-value))} && ret=0
  elif [[ -prefix - && $value -gt 0 ]]; then
    _wanted -V volume expl volume compadd $expl - -{1..$value} && ret=0
  else
    _wanted -V volume expl volume compadd $expl - {0..100} && ret=0
    compstate[insert]=menu:$((value+1))
  fi
  return ret
}

_mpc_repeat() {
  _mpc_helper_bool
}

_mpc_random() {
  _mpc_helper_bool
}

_mpc_single() {
  _mpc_helper_bool
}

_mpc_consume() {
  _mpc_helper_bool
}

_mpc_current() {
  _arguments --wait
}

_mpc_search() {
  local list expl
  list=(album artist title track name genre date composer performer comment disc filename any)

  if ! (( $#words % 2 )); then
    _wanted list expl table compadd $expl -a list
  else
    _message "pattern"
  fi
}

_mpc_find() {
  _mpc_search "$@"
}

_mpc_list() {
  _mpc_search "$@"
}

_mpc_update() {
  _mpc_helper_files
}

if [[ $service = *MPD_HOST* ]]; then
  _hosts
  return
fi

local curcontext="$curcontext" state line expl ret=1
local mpccmd="$words[1]"

_arguments -C \
  '(-q --quiet --no-status -v --verbose)'{-v,--verbose}'[give verbose output]' \
  '(-q --quiet --no-status -v --verbose)'{-q,--quiet,--no-status}'[prevent printing song status on completion]' \
  '(-h --host)'{-h,--host=}'[connect to specified host]:_hosts' \
  '(-p --port)'{-p,--port=}'[connect to server port]:port' \
  '(-f --format)'{-f,--format=}'[specify the format of song display]:format string:->formats' \
  '(-w --wait)'{-w,--wait}'[wait for operation to finish (e.g. database update)]' \
  '*::mpc command:_mpc_command' && ret=0

if [[ $state = formats ]]; then
  compset -P '([^%]|%[^%]#%)#'
  _wanted metadata expl 'metadata delimiter' compadd -p % -S % \
    artist album albumartist comment composer date disc genre performer title \
    track time file position mtime mdate && ret=0
fi

return ret