1#compdef dcop dcopstart dcopfind dcopref dcopclient dcopobject
2
3local curcontext="$curcontext" desc vals arg base max=0 ret=1
4local app obj fun
5local -a state line expl
6
7case $service in
8  dcop(client|object))
9    state=( dcopref )
10    max=2
11  ;;
12  dcopref) max=3 ;;
13  dcopstart)
14    if (( CURRENT > 2 )); then
15      _urls && return
16    fi
17  ;;
18  dcopfind)
19    local cmd=$words[1]
20    _arguments -C \
21      '-a[print application id instead of DCOPRef]' \
22      '-l[if object not found, run dcopstart and retry]' \
23      '*::args:->args' && ret=0
24    unset state
25    words=( $cmd $words )
26    (( CURRENT++ ))
27  ;;
28esac
29
30if (( max && CURRENT > max )); then
31  _message 'no more arguments'
32  return 1
33fi
34
35if [[ -z "$state" ]]; then
36  state=(application object function)
37  [[ $words[2] = DCOPRef* && CURRENT -ne 2 ]]
38  base=$?
39  state=( ${state[CURRENT-base]:-arg} )
40
41  [[ $state[1] = application && $service = dcop(|find) ]] && state+=( dcopref )
42fi
43
44while (( $#state )); do
45  unset app obj fun
46
47  if [[ $words[2] = (#b)DCOPRef*\(([^,]#)((#e)|,)([^\\\)]#)(*) ]]; then
48    if [[ -n $match[2] ]]; then
49      app=$match[1]
50      if [[ -n $match[4] ]]; then
51        obj=$match[3]
52	[[ -n $words[3] && CURRENT -gt 3 ]] && fun=$words[3]
53      fi
54    fi
55  else
56    case $CURRENT in
57      <5->) fun="$words[4]" ;&
58      4) obj="$words[3]" ;&
59      3) app="$words[2]" ;;
60    esac
61  fi
62  vals=( ${(f)"$(_call_program dcop-$state[1]s ${(M)words[1]##*/}dcop $app $obj 2>/dev/null)"} )
63
64  case "$state[1]" in
65    application|object)
66      [[ -n ${(M)vals:#*\(default\)} ]] && vals+=( default )
67      _wanted dcop-$state[1]s expl $state[1] compadd "$@" - ${vals% \(default\)} && ret=0
68    ;;
69
70    function)
71      [[ $service = dcopfind ]] && vals=( ${(M)vals:#bool *} )
72      _wanted dcop-$state[1]s expl $state[1] compadd "$@" - ${${vals#* }%\(*} && ret=0
73    ;;
74
75    arg)
76      arg=${${${(M)vals:#*$fun\(*}#*\(}%\)*},
77      arg=${${(s.,.)arg}[CURRENT-base-3]}
78      if [[ -n $arg ]]; then
79	if [[ $arg = (Q(|C)String|*int )* || $arg != *\ * ]]; then
80	  # don't mention the argument's type
81	  desc="${arg##* }"
82	else
83	  desc="${arg##* } (${arg% *})"
84	fi
85	case $arg in
86	  bool*) _wanted argument expl "$desc" compadd true false && return ;;
87	  (#i)*(file|path|dir)*) _wanted argument expl "$desc" _files && return ;;
88	  (#i)*url*) _wanted argument expl "$desc" _urls && return ;;
89	  *) _message -e argument "$desc" ;;
90	esac
91      else
92	_message 'no more arguments'
93      fi
94    ;;
95
96    dcopref)
97      if ! compset -P '*\('; then
98	_wanted dcoprefs expl 'dcop ref' compadd -S '' 'DCOPRef(' && ret=0
99      elif compset -P '*,'; then
100        if compset -S '(|\\)\)*'; then
101	  set -- -S '' "$@"
102	else
103	  set -- "$@" -S"${${QIPREFIX:+)}:-\)}$compstate[quote] "
104	fi
105        state+=( object )
106      else
107        if compset -S ',*'; then
108	  set -- "$@" -S ''
109	else
110	  set -- "$@" -S ,
111	fi
112        state+=( application )
113      fi
114    ;;
115  esac
116  shift state
117done
118
119return ret
120