181 lines
5 KiB
Bash
181 lines
5 KiB
Bash
#!/bin/zsh
|
|
zmodload -Fa zsh/files b:zf_rm
|
|
zmodload -F zsh/parameter p:funcstack p:functions
|
|
builtin autoload -Uz is-at-least
|
|
|
|
typeset -ga _autocomplete__compdef=()
|
|
compdef() {
|
|
typeset -ga _autocomplete__compdef=( $_autocomplete__compdef[@] "${(j: :)${(@q+)@}}" )
|
|
}
|
|
|
|
[[ -v functions[_bash_complete] ]] ||
|
|
_bash_complete compgen complete () {
|
|
unfunction _bash_complete compgen complete
|
|
builtin autoload +X -Uz bashcompinit
|
|
bashcompinit
|
|
bashcompinit() { : }
|
|
${(%):-%N} "$@"
|
|
}
|
|
|
|
${0}:precmd() {
|
|
emulate -L zsh
|
|
setopt $_autocomplete__func_opts[@]
|
|
|
|
[[ -v CDPATH && -z $CDPATH ]] &&
|
|
unset CDPATH cdpath
|
|
|
|
# Decrease Oh My Zsh start-up time. See below.
|
|
local -Pa omzdump=()
|
|
[[ -v ZSH_COMPDUMP && -r $ZSH_COMPDUMP ]] &&
|
|
omzdump=( ${(f)"$( < $ZSH_COMPDUMP )"} )
|
|
|
|
typeset -g \
|
|
_comp_dumpfile=${_comp_dumpfile:-${ZSH_COMPDUMP:-${XDG_CACHE_HOME:-$HOME/.cache}/zsh/compdump}}
|
|
|
|
if [[ -v _comps[-command-] && $_comps[-command-] != _autocomplete__command ]]; then
|
|
zf_rm -f $_comp_dumpfile
|
|
else
|
|
|
|
# Check if our most recently modified completion function is newer than the comp dump file.
|
|
local -Pa newest=( ~autocomplete/Completions/_*~*.zwc(N-.omY1) )
|
|
if [[ $newest[1] -nt $_comp_dumpfile ]]; then
|
|
zf_rm -f $_comp_dumpfile
|
|
fi
|
|
fi
|
|
|
|
if [[ ! -v _comp_setup ]] || [[ ! -r $_comp_dumpfile ]]; then
|
|
unfunction compdef compinit 2> /dev/null
|
|
bindkey() { : }
|
|
{
|
|
builtin autoload +X -Uz compinit
|
|
local -a compargs=()
|
|
zstyle -a ':autocomplete::compinit' arguments compargs
|
|
compinit -d "$_comp_dumpfile" "$compargs[@]"
|
|
} always {
|
|
unfunction bindkey
|
|
}
|
|
bindkey '^Xh' _complete_help
|
|
|
|
# Prevent Oh My Zsh from deleting comp dump file.
|
|
(( ${#omzdump[@]} > 0 )) &&
|
|
tee -a "$ZSH_COMPDUMP" &> /dev/null <<EOF
|
|
$omzdump[-2]
|
|
$omzdump[-1]
|
|
EOF
|
|
fi
|
|
|
|
compinit() { : }
|
|
|
|
local -P args=
|
|
for args in "$_autocomplete__compdef[@]"; do
|
|
eval "compdef $args"
|
|
done
|
|
unset _autocomplete__compdef
|
|
|
|
(
|
|
local -a reply=()
|
|
local cache_dir=
|
|
if builtin zstyle -s ':completion:*' cache-path cache_dir; then
|
|
local -P src= bin=
|
|
for src in $cache_dir/*~**.zwc~**/.*(N-.); do
|
|
bin=$src.zwc
|
|
if [[ ! -e $bin || $bin -ot $src ]]; then
|
|
zcompile -Uz $src
|
|
fi
|
|
done
|
|
fi
|
|
) &|
|
|
|
|
# Workaround: Some other plugins rely on patching _main_complete, which can interfere with our completion.
|
|
.autocomplete__patch _main_complete
|
|
autocomplete:_main_complete:new() {
|
|
local -i _autocomplete__reserved_lines=0
|
|
local -Pi ret=1
|
|
unset _autocomplete__partial_list _autocomplete__unambiguous
|
|
|
|
compstate[insert]=automenu-unambiguous # To get `all-expansions` from _expand.
|
|
compstate[last_prompt]=yes # Completion doesn't stay on the same command line without this.
|
|
compstate[list]='list force packed rows' # `_setup` doesn't work well for this.
|
|
unset 'compstate[vared]'
|
|
|
|
local +h -a compprefuncs=( autocomplete:_main_complete:new:pre "$compprefuncs[@]" )
|
|
local +h -a comppostfuncs=( autocomplete:_main_complete:new:post "$comppostfuncs[@]" )
|
|
autocomplete:_main_complete:old "$@"
|
|
}
|
|
|
|
autocomplete:_main_complete:new:pre() {
|
|
unsetopt localtraps
|
|
trap -
|
|
TRAPINT() { # ^C
|
|
zle -M "${(F)funcfiletrace}"
|
|
zle -R
|
|
return 130
|
|
}
|
|
TRAPQUIT() { # ^\
|
|
zle -M "${(F)funcfiletrace}"
|
|
zle -R
|
|
return 131
|
|
}
|
|
}
|
|
|
|
autocomplete:_main_complete:new:post() {
|
|
[[ $WIDGET != _complete_help ]] &&
|
|
unfunction compadd 2> /dev/null
|
|
_autocomplete__unambiguous
|
|
compstate[list_max]=0
|
|
MENUSCROLL=0
|
|
}
|
|
|
|
.autocomplete__patch _complete
|
|
_complete() {
|
|
local -i nmatches=$compstate[nmatches]
|
|
|
|
PREFIX=$PREFIX$SUFFIX
|
|
SUFFIX=
|
|
autocomplete:_complete:old "$@"
|
|
|
|
# WORKAROUND: Some completion functions mistakenly don't return 0 when they have succeeded.
|
|
(( compstate[nmatches] > nmatches ))
|
|
}
|
|
|
|
|
|
##
|
|
# WORKAROUND: _approximate won't do corrections if there already is a function called 'compadd'.
|
|
#
|
|
|
|
.autocomplete__patch _approximate
|
|
_approximate() {
|
|
{
|
|
[[ -v functions[compadd] ]] &&
|
|
functions[autocomplete:compadd:old]="$functions[compadd]"
|
|
functions[compadd]="$functions[autocomplete:approximate:compadd]"
|
|
|
|
autocomplete:_approximate:old
|
|
} always {
|
|
unfunction compadd 2> /dev/null
|
|
if [[ -v functions[autocomplete:compadd:old] ]]; then
|
|
functions[compadd]="$functions[autocomplete:compadd:old]"
|
|
unfunction autocomplete:compadd:old
|
|
fi
|
|
}
|
|
}
|
|
|
|
autocomplete:approximate:compadd() {
|
|
local ppre="$argv[(I)-p]"
|
|
|
|
[[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 &&
|
|
"${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return
|
|
|
|
if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then
|
|
PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}"
|
|
else
|
|
PREFIX="(#a${_comp_correct})$PREFIX"
|
|
fi
|
|
|
|
if [[ -v functions[autocomplete:compadd:old] ]]; then
|
|
autocomplete:compadd:old "$@"
|
|
else
|
|
builtin compadd "$@"
|
|
fi
|
|
}
|
|
}
|