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
|
#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
|