mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-27 04:40:59 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #compdef -k complete-word \C-x\C-r
 | |
| 
 | |
| # This allows an on-the-fly choice of completions.  On typing the key
 | |
| # sequence given above, you will be prompted for a string of arguments.  If
 | |
| # this string begins with `_', it will be taken as the name of a function to
 | |
| # evaluate to generate the completions; unambiguous strings in the function
 | |
| # name are automatically completed.
 | |
| #
 | |
| # Else it is taken to be a set of arguments for compadd to generate a list
 | |
| # of choices.  The possibilities are the same as the flags for generating
 | |
| # completions given in the zshcompwid manual page.  Note the arguments are
 | |
| # verbatim:  include minus signs, spaces, quotes, etc.
 | |
| #
 | |
| # On subsequent calls, the same completion will be re-performed.  To
 | |
| # force a new type of completion to be read, supply a numeric argument.
 | |
| #
 | |
| # For example,
 | |
| #  % bindkey | grep rever<C-xC-r>
 | |
| #  Completion: -b<RET>
 | |
| #  % bindkey | grep reverse-menu-complete _
 | |
| #
 | |
| # Global variables used:
 | |
| #  _read_comp         Last completion string read from user
 | |
| 
 | |
| # emulate -L zsh
 | |
| setopt localoptions extendedglob nobadpattern # xtrace promptsubst
 | |
| # local PS4='%N:%i:$((#key))> '
 | |
| 
 | |
| if [[ ${+NUMERIC} = 0 && -n $_read_comp ]]; then
 | |
|   if [[ $_read_comp = _* ]]; then
 | |
|     eval $_read_comp
 | |
|   else
 | |
|     eval "compadd $_read_comp"
 | |
|   fi
 | |
|   return
 | |
| fi
 | |
| 
 | |
| _read_comp=
 | |
| 
 | |
| local key search str str2 newch funcs funcs2 exact msg list
 | |
| integer pos
 | |
| 
 | |
| msg="Completion: "
 | |
| 
 | |
| zle -R $msg
 | |
| 
 | |
| if ! read -k key; then
 | |
|   zle -cR ''
 | |
|   return 1
 | |
| fi
 | |
| 
 | |
| while [[ '#key' -ne 10 && '#key' -ne 13 ]]; do
 | |
|   if [[ '#key' -eq 0 && '#key' -eq 3 || '#key' -eq 7 ]]; then
 | |
|     zle -cR ''
 | |
|     return 1
 | |
|   fi
 | |
|   if [[ ( '#key' -eq 8 || '#key' -eq 127 ) && -n $str ]]; then
 | |
|     # delete character
 | |
|     str="$str[1,-2]"
 | |
|     exact=
 | |
|     list=()
 | |
|   elif [[ '#key' -eq 21 ]]; then
 | |
|     # ^U: delete line
 | |
|     str=
 | |
|     exact=
 | |
|     list=()
 | |
|   elif [[ '#key' -eq 4 && $str = _[^\ ]# && $str != *' '* ]]; then
 | |
|     # ^D: list completions
 | |
|     list=(${$(whence -m "$str*" 2>/dev/null)%: function})
 | |
|   elif [[ ( -n $exact && $key != ' ' ) || '#key & 127' -lt 32 ]]; then
 | |
|     # If we've got an exact function, only allow a space after it.
 | |
|     # Don't try to insert non-printing characters.
 | |
|     if [[ -n $ZBEEP ]]; then
 | |
|       print -nb $ZBEEP
 | |
|     elif [[ -o beep ]]; then
 | |
|       print -n "\a"
 | |
|     fi
 | |
|     list=()
 | |
|   else
 | |
|     str="$str$key"
 | |
|     if [[ $str = _[^\ ]# ]]; then
 | |
|       # Rudimentary completion for function names.
 | |
|       # Allow arguments, i.e. don't do this after we've got a space.
 | |
|       funcs=(${$(whence -m "$str*" 2>/dev/null)%: function})
 | |
|       if [[ -o autolist && $#str -gt 1 ]]; then
 | |
| 	list=($funcs)
 | |
|       else
 | |
| 	list=()
 | |
|       fi
 | |
|       if (( $#funcs == 1 )); then
 | |
| 	# Exact match; prompt the user for a newline to confirm
 | |
| 	str=$funcs[1]
 | |
| 	exact=" (Confirm)"
 | |
|       elif (( $#funcs == 0 )); then
 | |
| 	# We can't call zle beep, because this isn't a zle widget.
 | |
| 	if [[ -n $ZBEEP ]]; then
 | |
| 	  print -nb $ZBEEP
 | |
| 	elif [[ -o beep ]]; then
 | |
| 	  print -n "\a"
 | |
| 	fi
 | |
| 	str="$str[1,-2]"
 | |
| 	list=()
 | |
|       else
 | |
| 	# Add characters to the string until a name doesn't
 | |
| 	# match any more, then backtrack one character to get
 | |
| 	# the longest unambiguous match.
 | |
| 	str2=$str
 | |
| 	pos=$#str2
 | |
| 	while true; do
 | |
| 	  (( pos++ ))
 | |
| 	  newch=${funcs[1][pos]}
 | |
| 	  [[ -z $newch ]] && break
 | |
| 	  str2=$str2$newch
 | |
| 	  funcs2=(${funcs##$str2*})
 | |
| 	  (( $#funcs2 )) && break
 | |
| 	  str=$str2
 | |
| 	done
 | |
|       fi
 | |
|     else
 | |
|       exact=
 | |
|     fi
 | |
|   fi
 | |
|   if (( $#list )); then
 | |
|     zle -R "$msg$str$exact" $list
 | |
|   else
 | |
|     zle -cR "$msg$str$exact"
 | |
|   fi
 | |
|   if ! read -k key; then
 | |
|     zle -cR ''
 | |
|     return 1
 | |
|   fi
 | |
| done
 | |
| 
 | |
| if [[ -z $str ]]; then
 | |
|   # string must be non-zero
 | |
|   return 1
 | |
| elif [[ $str = _* ]] && ! whence ${str%% *} >& /dev/null; then
 | |
|   # a function must be known to the shell
 | |
|   return 1
 | |
| else
 | |
|   # remember the string for re-use
 | |
|   _read_comp=$str
 | |
| fi
 | |
| 
 | |
| zle -cR ''
 | |
| 
 | |
| if [[ $str = _* ]]; then
 | |
|   eval $str
 | |
| else
 | |
|   eval "compadd $str"
 | |
| fi
 |