about summary refs log tree commit diff
path: root/Completion/Base/_describe
blob: e01c7750981f613b48e11ad619d87f0abd36a8af (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
#autoload

# This can be used to add options or values with descriptions as matches.

setopt localoptions extendedglob

local gdescr isopt cmd opt nsets tmp descr match descrs matches adescr i
local disps disp expl tmps tmpd tmpmd tmpms name ret=1 showd _nm

cmd="$words[1]"

# Get the options.

while getopts 'oc:' opt; do
  if [[ "$opt" = o ]]; then
    isopt=yes
  else
    cmd="$OPTARG"
  fi
done
shift OPTIND-1

# Do the tests. `showd' is set if the descriptions should be shown.

if [[ -n "$isopt" ]]; then

  # We take the value to test the number of patches from a non-local
  # parameter `nm' if that exists and contains only digits. It's a hack.

  if [[ "$nm" = [0-9]## ]]; then
    _nm="$nm"
  else
    _nm=0
  fi
  [[ -n "$compconfig[option_prefix]" &&
     "$compconfig[option_prefix]" != *\!${cmd}* &&
     "$PREFIX" != [-+]* &&
     ( "$compconfig[option_prefix]" = *nodefault* ||
       _nm -ne compstate[nmatches] ) ]] && return 1

  [[ -n "$compconfig[describe_options]" &&
     "$compconfig[describe_options]" != *\!${cmd}* ]] && showd=yes
else
  [[ -n "$compconfig[describe_values]" &&
     "$compconfig[describe_values]" != *\!${cmd}* ]] && showd=yes
fi

gdescr="$1"
shift

# Now interpret the arguments.

nsets=0
adescr=()
descrs=()
matches=()
while (( $# )); do
  (( nsets++ ))
  descr="$1"
  [[ -n "$showd" ]] && adescr=( "$adescr[@]" "${(@PM)^descr:#*:?*},$nsets" )
  if [[ "$2" = -* ]]; then
    match=''
    shift
  else
    match="$2"
    shift 2
  fi
  tmp=$argv[(i)--]
  if [[ tmp -eq 1 ]]; then
    opt=()
  else
    opt=( "${(@)argv[1,tmp-1]}" )
  fi
  if [[ tmp -gt $# ]]; then
    argv=()
  else
    shift tmp
  fi

  # `descr' and `matches' collect the names of the arrays containing the
  # possible matches with descriptions and the matches to add.
  # The options to give to `compadd' are stored in local arrays.

  descrs[nsets]="$descr"
  matches[nsets]="$match"
  typeset -a _descr_opts_$nsets
  eval "_descr_opts_${nsets}=( \"\$opt[@]\" )"
done

(( nsets )) || return 1

# Build the display strings if needed.

[[ -n "$showd" ]] && _display disps "$adescr[@]"
_description expl "$gdescr"

# Loop through the array/option sets we have.

i=0
while [[ ++i -le nsets ]]; do
  name=_descr_opts_$i
  [[ -n "$showd" ]] && disp=( "${(@)${(@M)disps:#*,${i}}%,*}" )
  descr=( "${(@P)descrs[i]}" )

  # We collect the strings to display in `tmpd' (one string per line)
  # and `tmps' (in columns) and the matches to add in `tmpmd' and `tmpms'.

  tmpd=()
  tmps=()
  tmpmd=()
  tmpms=()
  if [[ -n "$matches[i]" ]]; then
    match=( "${(@P)matches[i]}" )
    while (( $#match )); do
      if [[ -n "$showd" && "$descr[1]" = *:?* ]]; then
	tmpd=( "$tmpd[@]" "$disp[1]" )
        tmpmd=( "$tmpmd[@]" "$match[1]" )
        shift 1 disp
      else
        tmps=( "$tmps[@]" "${descr[1]%%:*}" )
        tmpms=( "$tmpms[@]" "$match[1]" )
      fi
      shift 1 match
      shift 1 descr
    done
  else
    while (( $#descr )); do
      if [[ -n "$showd" && "$descr[1]" = *:?* ]]; then
	tmpd=( "$tmpd[@]" "$disp[1]" )
        tmpmd=( "$tmpmd[@]" "${descr[1]%%:*}" )
        shift 1 disp
      else
        tmps=( "$tmps[@]" "${descr[1]%%:*}" )
        tmpms=( "$tmpms[@]" "${descr[1]%%:*}" )
      fi
      shift 1 descr
    done
  fi

  # See if we should remove the option prefix characters.

  if [[ -n "$isopt" && "$compconfig[option_prefix]" = hide* ]]; then
    if [[ "$PREFIX" = --* ]]; then
      tmpd=( "${(@)tmpd#--}" )
      tmps=( "${(@)tmps#--}" )
    elif [[ "$PREFIX" = [-+]* ]]; then
      tmpd=( "${(@)tmpd#[-+]}" )
      tmps=( "${(@)tmps#[-+]}" )
    fi
  fi
  compadd "${(@P)name}" "$expl[@]" -ld tmpd - "$tmpmd[@]" && ret=0
  compadd "${(@P)name}" "$expl[@]" -d tmps - "$tmpms[@]" && ret=0
done

return ret