mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-30 17:50:58 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			221 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| # Initialisation for new style completion. This mainly contains some helper
 | |
| # function and aliases. Everything else is split into different files in this
 | |
| # directory that will automatically be made autoloaded (see the end of this
 | |
| # file).
 | |
| # The names of the files that will be considered for autoloading have to
 | |
| # start with a underscores (like `_setopt).
 | |
| # The first line of these files will be read and has to say what should be
 | |
| # done with its contents:
 | |
| #
 | |
| #   `#defcomp <names ...>'
 | |
| #     if the first line looks like this, the file is
 | |
| #     autoloaded as a function and that function will
 | |
| #     be called to generate the matches when completing
 | |
| #     for one of the commands whose <name> is given
 | |
| #
 | |
| #   `#defpatcomp <pattern>'
 | |
| #     this defines a function that should be called to generate
 | |
| #     matches for commands whose name matches <pattern>; note
 | |
| #     that only one pattern may be given
 | |
| #
 | |
| #   `#defkeycomp <style> [ <key-sequence> ... ]
 | |
| #     this is used to bind special completions to all the given
 | |
| #     <key-sequence>(s). The <style> is the name of one of the built-in
 | |
| #     completion widgets (complete-word, delete-char-or-list,
 | |
| #     expand-or-complete, expand-or-complete-prefix, list-choices,
 | |
| #     menu-complete, menu-expand-or-complete, or reverse-menu-complete).
 | |
| #     This creates a widget behaving like <style> so that the
 | |
| #     completions are chosen as given in the the rest of the file,
 | |
| #     rather than by the context.  The widget has the same name as
 | |
| #     the autoload file and can be bound using bindkey in the normal way.
 | |
| #
 | |
| #   `#autoload'
 | |
| #     this is for helper functions that are not used to
 | |
| #     generate matches, but should automatically be loaded
 | |
| #     when they are called
 | |
| #
 | |
| # Note that no white space is allowed between the `#' and the rest of
 | |
| # the string.
 | |
| #
 | |
| # See the file `dump' for how to speed up initialiation.
 | |
| 
 | |
| # If we got the `-d'-flag, we will automatically dump the new state (at
 | |
| # the end).
 | |
| 
 | |
| if [[ "$1" = -d ]]; then
 | |
|   _i_autodump=1
 | |
| else
 | |
|   _i_autodump=0
 | |
| fi
 | |
| 
 | |
| # The associative array containing the definitions for the commands.
 | |
| # Definitions for patterns will be stored in the normal array `patcomps'.
 | |
| 
 | |
| typeset -A comps
 | |
| 
 | |
| 
 | |
| # This may be used to define completion handlers. The first argument is the
 | |
| # name of the function containing the definition, the other arguments are the
 | |
| # command names for which this definition should be used.
 | |
| # With only one argument the function/variable-name _$1 is used.
 | |
| # If given the `-a' option, the function is defined as being autoloaded.
 | |
| 
 | |
| defcomp() {
 | |
|   local name
 | |
| 
 | |
|   if [[ "$1" = -a ]]; then
 | |
|     shift
 | |
|     autol=yes
 | |
|   fi
 | |
|   if [[ $# -eq 1 ]]; then
 | |
|     comps[$1]="_$1"
 | |
|     [[ -z "$autol" ]] || autoload "_$1"
 | |
|   else
 | |
|     name="$1"
 | |
|     shift
 | |
|     for i; do
 | |
|       comps[$i]="$name"
 | |
|     done
 | |
|     [[ -z "$autol" ]] || autoload "$name"
 | |
|   fi
 | |
| }
 | |
| 
 | |
| # Almost like `defcomp', but this always gets two arguments: the name of a
 | |
| # function describing what should be completed and the pattern that will be
 | |
| # compared to the command names for which completion is attempted.
 | |
| 
 | |
| defpatcomp() {
 | |
|   if [[ "$1" = -a ]]; then
 | |
|     shift
 | |
|     autoload "$1"
 | |
|   fi
 | |
|   if (( $+patcomps )) then
 | |
|     patcomps=("$patcomps[@]" "$2 $1")
 | |
|   else
 | |
|     patcomps=("$2 $1")
 | |
|   fi
 | |
| }
 | |
| 
 | |
| # This is used to define completion handlers directly bound to keys. The
 | |
| # first argument is as for `defcomp', giving the handler. The second
 | |
| # argument is the name of one of the built-in completion widgets. Any
 | |
| # remaining arguments are used as key sequences to bind the widget.
 | |
| # Typing that key sequence will complete the word the cursor is on
 | |
| # according to the completion definition given and will behave as if the
 | |
| # built-in completion widget was used.
 | |
| 
 | |
| defkeycomp() {
 | |
|   local name
 | |
| 
 | |
|   if [[ "$1" = -a ]]; then
 | |
|     shift
 | |
|     autoload "$1"
 | |
|   fi
 | |
|   name="$1"
 | |
|   shift
 | |
|   zle -C "$name" "$1" "$name"
 | |
|   shift
 | |
|   while (( $# )); do
 | |
|     bindkey "$1" "$name"
 | |
|     shift
 | |
|   done
 | |
| }
 | |
| 
 | |
| # This searches $1 in the array for normal completions and calls the result.
 | |
| 
 | |
| _compalso() {
 | |
|   local tmp
 | |
| 
 | |
|   tmp="$comps[$1]"
 | |
|   [[ -z "$tmp" ]] || "$tmp" "$@"
 | |
| }
 | |
| 
 | |
| # These can be used to easily save and restore the state of the special
 | |
| # variables used by the completion code.
 | |
| 
 | |
| alias _compsave='local _oprefix$_level _oiprefix$_level _oargv$_level _ocurrent$_level _ocommand$_level _ocontext$_level; \
 | |
|                 eval "_oprefix${_level}=\"\$PREFIX\"; \
 | |
|                       _oiprefix${_level}=\"\$IPREFIX\"; \
 | |
|                       _oargv${_level}=( \"\$@\" ); \
 | |
|                       _ocurrent${_level}=\"\$CURRENT\"; \
 | |
| 		      _ocommand${_level}=\"\$COMMAND\"; \
 | |
| 		      _ocontext${_level}=\"\$CONTEXT\""'
 | |
| alias _compreset='eval "PREFIX=\"\$_oprefix${_level}\"; \
 | |
|                         IPREFIX=\"\$_oiprefix${_level}\"; \
 | |
|                         argv=( \"\$_oargv${_level}[@]\" ); \
 | |
| 	  	        CURRENT=\"\$_ocur${_level}\"; \
 | |
|                         COMMAND=\"\$_ocommand${_level}\"; \
 | |
|                         CONTEXT=\"\$_ocontext${_level}\""'
 | |
| 
 | |
| # These can be used to build tests that modify the special parameters
 | |
| # without having to reset them by hand.
 | |
| 
 | |
| alias _if='(( $+_level )) || local _level=0; (( _level++ )); _compsave; if'
 | |
| alias _elif='_compreset; elif'
 | |
| alias _else='_compreset; else'
 | |
| alias _fi='_compreset; fi; unset _oprefix$_level _oiprefix$_level _oargv$_level _ocurrent$_level _ocommand$_level _ocontext$_level; (( _level-- ))'
 | |
| 
 | |
| 
 | |
| # Now we automatically make the definition files autoloaded.
 | |
| 
 | |
| # First we get the name of a dump file if this will be used.
 | |
| 
 | |
| : ${COMPDUMP:=$0.dump}
 | |
| 
 | |
| _i_files=( ${^~fpath}/_*~*~ )
 | |
| _i_initname=$0
 | |
| _i_done=''
 | |
| 
 | |
| # If we have a dump file, load it.
 | |
| 
 | |
| if [[ -f "$COMPDUMP" ]]; then
 | |
|   read -rA _i_line < "$COMPDUMP"
 | |
|   if [[ _i_autodump -eq 1 || $_i_line[2] -eq $#_i_files ]]; then
 | |
|     builtin . "$COMPDUMP"
 | |
|     _i_done=yes
 | |
|   fi
 | |
|   unset _i_line
 | |
| fi
 | |
| if [[ -z "$_i_done" ]]; then
 | |
| 
 | |
|   for _i_dir in $fpath; do
 | |
|     [[ $_i_dir = . ]] && continue
 | |
|     for _i_file in $_i_dir/_*~*~(N); do
 | |
|       read -rA _i_line < $_i_file
 | |
|       _i_tag=$_i_line[1]
 | |
|       shift _i_line
 | |
|       if [[ $_i_tag = '#defcomp' ]]; then
 | |
| 	defcomp -a ${_i_file:t} "${_i_line[@]}"
 | |
|       elif [[ $_i_tag = '#defpatcomp' ]]; then
 | |
| 	defpatcomp -a "${_i_file:t}" "${_i_line[@]}"
 | |
|       elif [[ $_i_tag = '#defkeycomp' ]]; then
 | |
| 	defkeycomp -a "${_i_file:t}" "${_i_line[@]}"
 | |
|       elif [[ $_i_tag = '#autoload' ]]; then
 | |
| 	autoload ${_i_file:t}
 | |
|       fi
 | |
|     done
 | |
|   done
 | |
| 
 | |
|   bindkey |
 | |
|     while read -rA _i_line; do
 | |
|       if [[ "$_i_line[2]" = complete-word ||
 | |
| 	"$_i_line[2]" = delete-char-or-list ||
 | |
| 	"$_i_line[2]" = expand-or-complete ||
 | |
| 	"$_i_line[2]" = expand-or-complete-prefix ||
 | |
| 	"$_i_line[2]" = list-choices ||
 | |
| 	"$_i_line[2]" = menu-complete ||
 | |
| 	"$_i_line[2]" = menu-expand-or-complete ||
 | |
| 	"$_i_line[2]" = reverse-menu-complete ]]; then
 | |
| 	zle -C _complete_$_i_line[2] $_i_line[2] _main_complete
 | |
| 	bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2]
 | |
|       fi
 | |
|     done
 | |
| 
 | |
|   unset _i_dir _i_line _i_file _i_tag
 | |
| 
 | |
|   # if autodumping was requested, do it now.
 | |
| 
 | |
|   (( _i_autodump )) && builtin . ${_i_initname:h}/dump
 | |
| fi
 | |
| 
 | |
| unset _i_files _i_initname _i_done _i_autodump
 |