mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 06:00:54 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			277 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #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
 | |
| exec </dev/null	# ZLE closes stdin, which can cause errors
 | |
| 
 | |
| # Failed returns from this code are not real errors
 | |
| setopt localtraps noerrexit ; trap - ZERR
 | |
| 
 | |
| local func funcs ret=1 tmp _compskip format nm call \
 | |
|       _completers _completer _completer_num curtag _comp_force_list \
 | |
|       _matchers _matcher _matcher_num _comp_tags _comp_mesg \
 | |
|       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]}" \
 | |
|       _saved_colors="$ZLS_COLORS"
 | |
| 
 | |
| typeset -U _lastdescr _comp_ignore
 | |
| 
 | |
| [[ -z "$curcontext" ]] && curcontext=:::
 | |
| 
 | |
| if [[ "$compstate[insert]" = tab* && "$WIDGET" != *list* ]]; then
 | |
|   { zstyle -T ":completion:${curcontext}:" insert-tab &&
 | |
|     { [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
 | |
|         zstyle -t ":completion:vared${curcontext}:" insert-tab } } && return 0
 | |
| 
 | |
|   compstate[insert]="${compstate[insert]//tab /}"
 | |
| fi
 | |
| 
 | |
| # Special completion contexts after `~' and `='.
 | |
| 
 | |
| if [[ -z "$compstate[quote]" ]]; then
 | |
|   if compset -P 1 '='; then
 | |
|     compstate[context]=equal
 | |
|   elif [[ "$PREFIX" != */* && "$PREFIX[1]" = '~' ]]; then
 | |
|     compset -p 1
 | |
|     compstate[context]=tilde
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| # Initial setup.
 | |
| 
 | |
| _setup default
 | |
| _def_menu_style=( "$_last_menu_style[@]"
 | |
| 
 | |
| # We can't really do that because the current value of $MENUSELECT
 | |
| # may be the one set by this function.
 | |
| # There is a similar problem with $ZLS_COLORS in _setup.
 | |
| 
 | |
| #                  ${MENUSELECT+select${MENUSELECT:+\=$MENUSELECT}}
 | |
| 
 | |
|                 )
 | |
| _last_menu_style=()
 | |
| 
 | |
| if zstyle -s ":completion:${curcontext}:default" list-prompt tmp; then
 | |
|   LISTPROMPT="$tmp"
 | |
|   zmodload -i zsh/complist
 | |
| fi
 | |
| if zstyle -s ":completion:${curcontext}:default" select-prompt tmp; then
 | |
|   MENUPROMPT="$tmp"
 | |
|   zmodload -i zsh/complist
 | |
| fi
 | |
| if zstyle -s ":completion:${curcontext}:default" select-scroll tmp; then
 | |
|   MENUSCROLL="$tmp"
 | |
|   zmodload -i zsh/complist
 | |
| fi
 | |
| 
 | |
| # Get the names of the completers to use in the positional parameters.
 | |
| 
 | |
| if (( $# )); then
 | |
|   if [[ "$1" = - ]]; then
 | |
|     if [[ $# -lt 3 ]]; then
 | |
|       _completers=()
 | |
|     else
 | |
|       _completers=( "$2" )
 | |
|       call=yes
 | |
|     fi
 | |
|   else
 | |
|     _completers=( "$@" )
 | |
|   fi
 | |
| else
 | |
|   zstyle -a ":completion:${curcontext}:" completer _completers ||
 | |
|       _completers=( _complete _ignored )
 | |
| fi
 | |
| 
 | |
| # And now just call the completer functions defined.
 | |
| 
 | |
| _completer_num=1
 | |
| 
 | |
| # Call the pre-functions.
 | |
| 
 | |
| funcs=( "$compprefuncs[@]" )
 | |
| compprefuncs=()
 | |
| for func in "$funcs[@]"; do
 | |
|   "$func"
 | |
| done
 | |
| 
 | |
| for tmp in "$_completers[@]"; do
 | |
| 
 | |
|   if [[ -n "$call" ]]; then
 | |
|     _completer="${tmp}"
 | |
|   elif [[ "$tmp" = *:-* ]]; then
 | |
|     _completer="${${tmp%:*}[2,-1]//_/-}${tmp#*:}"
 | |
|     tmp="${tmp%:*}"
 | |
|   elif [[ $tmp = *:* ]]; then
 | |
|     _completer="${tmp#*:}"
 | |
|     tmp="${tmp%:*}"
 | |
|   else
 | |
|     _completer="${tmp[2,-1]//_/-}"
 | |
|   fi
 | |
|   curcontext="${curcontext/:[^:]#:/:${_completer}:}"
 | |
| 
 | |
|   zstyle -a ":completion:${curcontext}:" matcher-list _matchers ||
 | |
|       _matchers=( '' )
 | |
| 
 | |
|   _matcher_num=1
 | |
|   for _matcher in "$_matchers[@]"; do
 | |
|     if [[ -n "$call" ]]; then
 | |
|       if "${(@)argv[3,-1]}"; then
 | |
|         ret=0
 | |
|         break 2
 | |
|       fi
 | |
|     elif "$tmp"; then
 | |
|       ret=0
 | |
|       break 2
 | |
|     fi
 | |
|     (( _matcher_num++ ))
 | |
|   done
 | |
|   (( _completer_num++ ))
 | |
| done
 | |
| 
 | |
| curcontext="${curcontext/:[^:]#:/::}"
 | |
| nm=$compstate[nmatches]
 | |
| 
 | |
| if [[ $compstate[old_list] = keep || nm -gt 1 ]]; then
 | |
|   [[ _last_nmatches -ge 0 && _last_nmatches -ne nm ]] &&
 | |
|       _menu_style=( "$_last_menu_style[@]" "$_menu_style[@]" )
 | |
| 
 | |
|   tmp=$(( compstate[list_lines] + BUFFERLINES + 1 ))
 | |
| 
 | |
|   _menu_style=( "$_menu_style[@]" "$_def_menu_style[@]" )
 | |
| 
 | |
|   if [[ "$compstate[list]" = *list &&
 | |
|         -n "$_menu_style[(r)select=long-list]" && tmp -gt LINES ]]; then
 | |
|     compstate[insert]=menu
 | |
|   elif [[ "$compstate[insert]" = "$_saved_insert" ]]; then
 | |
|     if [[ -n "$_menu_style[(r)select=long]" && tmp -gt LINES ]]; then
 | |
|         compstate[insert]=menu
 | |
|     elif [[ -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
 | |
| 
 | |
|   if [[ "$compstate[insert]" = *menu* ]]; then
 | |
|     if [[ -n "$_menu_style[(r)no-select*]" ]]; then
 | |
|       unset MENUSELECT
 | |
|     elif [[ -n "$_menu_style[(r)select=long*]" ]]; then
 | |
|       if [[ tmp -gt LINES ]]; then
 | |
|         zmodload -i zsh/complist
 | |
|         MENUSELECT=0
 | |
|       fi
 | |
|     fi
 | |
|     if [[ "$MENUSELECT" != 0 ]]; then
 | |
|       sel=( "${(@M)_menu_style:#select*}" )
 | |
| 
 | |
|       if (( $#sel )); 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
 | |
| 
 | |
|         zmodload -i zsh/complist
 | |
|         MENUSELECT="$min"
 | |
|       else
 | |
|         unset MENUSELECT
 | |
|       fi
 | |
|     fi
 | |
|   fi
 | |
| elif [[ nm -eq 0 && -n "$_comp_mesg" ]]; then
 | |
|   compstate[insert]=''
 | |
|   compstate[list]='list force'
 | |
| elif [[ nm -eq 0 &&
 | |
|         $#_lastdescr -ne 0 && $compstate[old_list] != keep ]] &&
 | |
|      zstyle -s ":completion:${curcontext}:warnings" format format; then
 | |
| 
 | |
|   compstate[list]='list force'
 | |
|   compstate[insert]=''
 | |
| 
 | |
|   if [[ "$format" = *%d* ]]; then
 | |
|     local str mesg
 | |
| 
 | |
|     _lastdescr=( "\`${(@)^_lastdescr:#}'" )
 | |
| 
 | |
|     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 mesg "$format" "d:$str"
 | |
|     compadd -UX "$mesg" -n - ''
 | |
|   else
 | |
|     _setup warnings
 | |
|     compadd -UQX "$format" -V warnings - "${(@)_lastdescr:#}"
 | |
|   fi
 | |
| fi
 | |
| 
 | |
| [[ "$_comp_force_list" = always ||
 | |
|    ( "$_comp_force_list" = ?*  && nm -ge _comp_force_list ) ]] &&
 | |
|     compstate[list]="$compstate[list] force"
 | |
| 
 | |
| [[ "$compstate[old_list]" = keep ]] && ZLS_COLORS="$_saved_colors"
 | |
| 
 | |
| # Now call the post-functions.
 | |
| 
 | |
| funcs=( "$comppostfuncs[@]" )
 | |
| comppostfuncs=()
 | |
| for func in "$funcs[@]"; do
 | |
|   "$func"
 | |
| done
 | |
| 
 | |
| _lastcomp=( "${(@kv)compstate}" )
 | |
| _lastcomp[nmatches]=$nm
 | |
| _lastcomp[completer]="$_completer"
 | |
| _lastcomp[prefix]="$PREFIX"
 | |
| _lastcomp[suffix]="$SUFFIX"
 | |
| _lastcomp[iprefix]="$IPREFIX"
 | |
| _lastcomp[isuffix]="$ISUFFIX"
 | |
| _lastcomp[qiprefix]="$QIPREFIX"
 | |
| _lastcomp[qisuffix]="$QISUFFIX"
 | |
| _lastcomp[tags]="$_comp_tags"
 | |
| 
 | |
| return ret
 |