about summary refs log tree commit diff
path: root/Completion/Core/_main_complete
blob: 53af97daba2ebeb1f582ee91d796c457fce4c91b (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
#autoload

# The main loop of the completion code. This is what is called when 
# completion is attempted from the command line.


# If you want to complete only set or unset options for the unsetopt
# and setopt builtin, un-comment these lines:
#
#   local _set_options _unset_options
#
#   _set_options=(${(k)options[(R)on]})
#   _unset_options=(${(k)options[(R)off]})
#
# This is needed because completion functions may set options locally
# which makes the output of setopt and unsetopt reflect a different
# state than the global one for which you are completing.

setopt localoptions nullglob rcexpandparam extendedglob
unsetopt markdirs globsubst shwordsplit nounset ksharrays

local comp post ret=1 _compskip _prio_num=1 format \
      context state line opt_args val_args curcontext="$curcontext" \
      _last_nmatches=-1 _last_menu_style _def_menu_style _menu_style sel \
      _saved_exact="${compstate[exact]}" \
      _saved_lastprompt="${compstate[last_prompt]}" \
      _saved_list="${compstate[list]}" \
      _saved_insert="${compstate[insert]}"

typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags

_offered_tags=()
_tried_tags=()
_failed_tags=()

typeset -U _lastdescr

# Special completion contexts after `~' and `='.

if compset -P 1 '='; then
  compstate[context]=equal
elif [[ "$PREFIX" != */* && "$PREFIX[1]" = '~' ]]; then
  compset -p 1
  compstate[context]=tilde
fi

# Initial setup.

_setup default
_def_menu_style=( "$_last_menu_style[@]" )
_last_menu_style=()

# Get the names of the completers to use in the positional parameters.

if (( ! $# )); then
  local tmp

  zstyle -a ":completion${curcontext}:" completer tmp
  set -- "$tmp[@]"
fi

# And now just call the completer functions defined.

for comp; do
  if "$comp"; then
    ret=0
    break;
  fi
done

if (( $compstate[nmatches] )); then
  [[ _last_nmatches -ge 0 && _last_nmatches -ne compstate[nmatches] ]] &&
      _menu_style=( "$_last_menu_style[@]" "$_menu_style[@]" )

  if [[ "$compstate[insert]" = "$_saved_insert" ]]; then
    if [[ -n "$_menu_style[(r)(yes|true|1|on)]" ||
          ( -n "$_menu_style[(r)auto*]" &&
            "$compstate[insert]" = automenu ) ]]; then
      compstate[insert]=menu
    elif [[ -n "$_menu_style[(r)auto*]" &&
            "$compstate[insert]" != automenu ]]; then
      compstate[insert]=automenu-unambiguous
    elif [[ -n "$_menu_style[(r)(no|false|0|off)]" ]]; then
      compstate[insert]=unambiguous
    elif [[ -n "$_def_menu_style[(r)(yes|true|1|on)]" ||
          ( -n "$_def_menu_style[(r)auto*]" &&
            "$compstate[insert]" = automenu ) ]]; then
      compstate[insert]=menu
    elif [[ -n "$_def_menu_style[(r)auto*]" &&
            "$compstate[insert]" != automenu ]]; then
      compstate[insert]=automenu-unambiguous
    elif [[ -n "$_def_menu_style[(r)(no|false|0|off)]" ]]; then
      compstate[insert]=unambiguous
    fi
  fi

  _menu_style=( "$_menu_style[@]" "$_def_menu_style[@]" )

  if [[ "$compstate[insert]" = *menu ]]; then
    if [[ -n "$_menu_style[(r)no-select*]" ]]; then
      unset SELECTMIN
    else
      sel=( "${(@M)_menu_style:#select*}" )

      if (( $# )); then
        local min=9999999 i num

        for i in "$sel[@]"; do
          if [[ "$i" = *\=* ]]; then
  	    num="${i#*\=}"
  	    [[ num -lt 0 ]] && num=0
  	  else
  	    num=0
  	  fi
  	  [[ num -lt min ]] && min="$num"
  
	  (( min )) || break
        done

        SELECTMIN="$min"
      fi
    fi
  fi
elif [[ compstate[matcher] -eq compstate[total_matchers] &&
        $#_lastdescr -ne 0 ]] &&
     zstyle -s ":completion${curcontext}:warnings" format format; then
  local str

  _lastdescr=( "\`${(@)^_lastdescr:#}'" )

  compstate[list]='list force'
  compstate[insert]=''

  case $#_lastdescr in
  1) str="$_lastdescr[1]";;
  2) str="$_lastdescr[1] or $_lastdescr[2]";;
  *) str="${(j:, :)_lastdescr[1,-2]}, or $_lastdescr[-1]";;
  esac

  zformat -f format "$format" "d:$str"
  compadd -UX "$format" -n ''
fi

if [[ compstate[matcher] -eq compstate[total_matchers] ||
      compstate[nmatches] -ne 0 ]]; then

  # See which tags were or were not used.

  _used_tags=( "${(@)_tried_tags:#${(j:|:)~${(@)_failed_tags//\[/\\[}//\]/\\]}}" )
  _unused_tags=( "${(@)_offered_tags:#${(j:|:)~${(@)_used_tags//\[/\\[}//\]/\\]}}" )

  # Now call the post-functions.

  for post in "$comppostfuncs[@]"; do
    "$post"
  done
  comppostfuncs=()

  _lastcomp=( "${(@kv)compstate}" )
  _lastcomp[completer]="$comp"
  _lastcomp[prefix]="$PREFIX"
  _lastcomp[suffix]="$SUFFIX"
  _lastcomp[iprefix]="$IPREFIX"
  _lastcomp[isuffix]="$ISUFFIX"
  _lastcomp[qiprefix]="$QIPREFIX"
  _lastcomp[qisuffix]="$QISUFFIX"
  _lastcomp[offered_tags]="${(j.:.)_offered_tags}"
  _lastcomp[tried_tags]="${(j.:.)_tried_tags}"
  _lastcomp[failed_tags]="${(j.:.)_failed_tags}"
  _lastcomp[unused_tags]="${(j.:.)_unused_tags}"
  _lastcomp[used_tags]="${(j.:.)_used_tags}"
fi

return ret