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


local comp post ret=1 _compskip _prio_num=1 _cur_context 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

setopt localoptions nullglob rcexpandparam extendedglob
unsetopt markdirs globsubst shwordsplit nounset ksharrays

# 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

  _style -a '' completer tmp
  set -- "$tmp[@]"
fi

# And now just call the completer functions defined.

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

# 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=()

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

[[ _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

if [[ compstate[nmatches] -eq 0 &&
      compstate[matcher] -eq compstate[total_matchers] &&
      $#_lastdescr -ne 0 ]] &&
   _style -s warnings format format; then
  local str

  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

  compadd -UX "${format//\\%d/$str}" -n ''
fi

_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}"

return ret