mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-29 06:51:03 +02:00
131 lines
3.8 KiB
Text
131 lines
3.8 KiB
Text
#autoload
|
|
|
|
# This code will try to correct the string on the line based on the
|
|
# strings generated for the context. These corrected strings will be
|
|
# shown in a list and one can cycle through them as in a menucompletion
|
|
# or get the corrected prefix.
|
|
|
|
local _comp_correct _correct_prompt comax
|
|
local cfgacc cfgorig cfgps cfgins
|
|
|
|
# Only if all global matchers have been tried.
|
|
|
|
[[ compstate[matcher] -ne compstate[total_matchers] ]] && return 1
|
|
|
|
# We don't try correction if the string is too short.
|
|
|
|
[[ "${#:-$PREFIX$SUFFIX}" -le 1 ]] && return 1
|
|
|
|
# Get the configuration values, using either the prefix `correct' or
|
|
# `approximate'.
|
|
|
|
if [[ "$compstate[pattern_match]" = (|\**) ]]; then
|
|
cfgacc="${compconfig[approximate_accept]:-$compconfig[correct_accept]}"
|
|
cfgorig="${compconfig[approximate_original]:-$compconfig[correct_original]}"
|
|
cfgps="${compconfig[approximate_prompt]:-$compconfig[correct_prompt]}"
|
|
cfgins="${compconfig[approximate_insert]:-$compconfig[correct_insert]}"
|
|
else
|
|
cfgacc="$compconfig[correct_accept]"
|
|
cfgorig="$compconfig[correct_original]"
|
|
cfgps="$compconfig[correct_prompt]"
|
|
cfgins="$compconfig[correct_insert]"
|
|
fi
|
|
|
|
# Get the number of errors to accept.
|
|
|
|
if [[ "$cfgacc" = *[nN]* && ${NUMERIC:-1} -ne 1 ]]; then
|
|
# Stop if we also have a `!'.
|
|
|
|
[[ "$cfgacc" = *\!* ]] && return 1
|
|
|
|
# Prefer the numeric argument if that has a sensible value.
|
|
|
|
comax="${NUMERIC:-1}"
|
|
else
|
|
comax="${cfgacc//[^0-9]}"
|
|
fi
|
|
|
|
# If the number of errors to accept is too small, give up.
|
|
|
|
[[ "$comax" -lt 1 ]] && return 1
|
|
|
|
# Otherwise temporarily define functions to use instead of
|
|
# the builtins that add matches. This is used to be able
|
|
# to stick the `(#a...)' into the right place (after an
|
|
# ignored prefix).
|
|
|
|
compadd() {
|
|
[[ "$*" != *-([a-zA-Z/]#|)U* &&
|
|
"${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return
|
|
|
|
if [[ "$PREFIX" = \~*/* ]]; then
|
|
PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}"
|
|
else
|
|
PREFIX="(#a${_comp_correct})$PREFIX"
|
|
fi
|
|
if [[ -n "$_correct_prompt" ]]; then
|
|
builtin compadd -X "$_correct_prompt" -J _correct "$@"
|
|
else
|
|
builtin compadd -J _correct "$@"
|
|
fi
|
|
}
|
|
|
|
# Now initialise our counter. We also set `compstate[matcher]'
|
|
# to `-1'. This allows completion functions to use the simple
|
|
# `[[ compstate[matcher] -gt 1 ]] && return' to avoid being
|
|
# called for multiple global match specs and still be called
|
|
# again when correction is done. Also, this makes it easy to
|
|
# test if correction is attempted since `compstate[matcher]'
|
|
# will never be set to a negative value by the completion code.
|
|
|
|
_comp_correct=1
|
|
compstate[matcher]=-1
|
|
|
|
_correct_prompt="${cfgps//\\%e/1}"
|
|
|
|
[[ -z "$compstate[pattern_match]" ]] && compstate[pattern_match]='*'
|
|
|
|
while [[ _comp_correct -le comax ]]; do
|
|
if _complete; then
|
|
if [[ "$cfgins" = unambig* &&
|
|
"${#compstate[unambiguous]}" -ge "${#:-$PREFIX$SUFFIX}" ]]; then
|
|
compstate[pattern_insert]=unambiguous
|
|
elif [[ compstate[nmatches] -gt 1 || "$cfgorig" = *always* ]]; then
|
|
local expl
|
|
|
|
if [[ "$cfgorig" = *show* ]]; then
|
|
if [[ -n "$compconfig[description_format]" ]]; then
|
|
expl=(-X "${compconfig[description_format]//\\%d/original}")
|
|
else
|
|
expl=()
|
|
fi
|
|
else
|
|
expl=(-n)
|
|
fi
|
|
if [[ "$cfgorig" = *last* ]]; then
|
|
builtin compadd "$expl[@]" -U -V _correct_original -Q - "$PREFIX$SUFFIX"
|
|
elif [[ -n "$cfgorig" ]]; then
|
|
builtin compadd "$expl[@]" -U -Q - "$PREFIX$SUFFIX"
|
|
fi
|
|
|
|
# If you always want to see the list of possible corrections,
|
|
# set `compstate[list]=list' here.
|
|
|
|
compstate[force_list]=list
|
|
fi
|
|
compstate[matcher]="$compstate[total_matchers]"
|
|
unfunction compadd
|
|
|
|
return 0
|
|
fi
|
|
|
|
[[ "${#:-$PREFIX$SUFFIX}" -le _comp_correct+1 ]] && break
|
|
(( _comp_correct++ ))
|
|
|
|
_correct_prompt="${cfgps//\\%e/$_comp_correct}"
|
|
done
|
|
|
|
compstate[matcher]="$compstate[total_matchers]"
|
|
unfunction compadd
|
|
|
|
return 1
|