Perf: memoize _zsh_highlight_main_highlighter_check_path

This commit is contained in:
Roman Perepelitsa 2020-08-16 11:34:16 +02:00
parent 4cf464f843
commit 826aa7312d

View File

@ -1182,98 +1182,117 @@ _zsh_highlight_main_highlighter_highlight_path_separators()
# $2 should be non-zero iff we're in command position. # $2 should be non-zero iff we're in command position.
_zsh_highlight_main_highlighter_check_path() _zsh_highlight_main_highlighter_check_path()
{ {
_zsh_highlight_main_highlighter_expand_path "$1" if (( $+_zsh_highlight_main__path_cache )); then
local expanded_path="$REPLY" tmp_path local cache_key=$1$'\0'$2
integer in_command_position=$2 if (( has_end && len == end_pos && !in_alias )) && [[ $WIDGET != zle-line-finish ]]; then
cache_key+=$'\0'
if [[ $zsyh_user_options[autocd] == on ]]; then
integer autocd=1
else
integer autocd=0
fi
if (( in_command_position )); then
# ### Currently, this value is never returned: either it's overwritten
# ### below, or the return code is non-zero
REPLY=arg0
else
REPLY=path
fi
if [[ ${1[1]} == '=' && $1 == ??* && ${1[2]} != $'\x28' && $zsyh_user_options[equals] == 'on' && $expanded_path[1] != '/' ]]; then
REPLY=unknown-token # will error out if executed
return 0
fi
[[ -z $expanded_path ]] && return 1
# Check if this is a blacklisted path
if [[ $expanded_path[1] == / ]]; then
tmp_path=$expanded_path
else
tmp_path=$PWD/$expanded_path
fi
tmp_path=$tmp_path:a
while [[ $tmp_path != / ]]; do
[[ -n ${(M)ZSH_HIGHLIGHT_DIRS_BLACKLIST:#$tmp_path} ]] && return 1
tmp_path=$tmp_path:h
done
if (( in_command_position )); then
if [[ -x $expanded_path ]]; then
if (( autocd )); then
if [[ -d $expanded_path ]]; then
REPLY=autodirectory
fi
return 0
elif [[ ! -d $expanded_path ]]; then
# ### This seems unreachable for the current callers
return 0
fi
fi fi
else local cache_val=$_zsh_highlight_main__path_cache[$cache_key]
if [[ -L $expanded_path || -e $expanded_path ]]; then if [[ -n $cache_val ]]; then
REPLY=${cache_val:1}
return $cache_val[1]
fi
fi
{
_zsh_highlight_main_highlighter_expand_path "$1"
local expanded_path="$REPLY" tmp_path
integer in_command_position=$2
if [[ $zsyh_user_options[autocd] == on ]]; then
integer autocd=1
else
integer autocd=0
fi
if (( in_command_position )); then
# ### Currently, this value is never returned: either it's overwritten
# ### below, or the return code is non-zero
REPLY=arg0
else
REPLY=path
fi
if [[ ${1[1]} == '=' && $1 == ??* && ${1[2]} != $'\x28' && $zsyh_user_options[equals] == 'on' && $expanded_path[1] != '/' ]]; then
REPLY=unknown-token # will error out if executed
return 0 return 0
fi fi
fi
# Search the path in CDPATH [[ -z $expanded_path ]] && return 1
if [[ $expanded_path != /* ]] && (( autocd || ! in_command_position )); then
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here. # Check if this is a blacklisted path
local cdpath_dir if [[ $expanded_path[1] == / ]]; then
for cdpath_dir in $cdpath ; do tmp_path=$expanded_path
if [[ -d "$cdpath_dir/$expanded_path" && -x "$cdpath_dir/$expanded_path" ]]; then else
if (( in_command_position && autocd )); then tmp_path=$PWD/$expanded_path
REPLY=autodirectory fi
tmp_path=$tmp_path:a
while [[ $tmp_path != / ]]; do
[[ -n ${(M)ZSH_HIGHLIGHT_DIRS_BLACKLIST:#$tmp_path} ]] && return 1
tmp_path=$tmp_path:h
done
if (( in_command_position )); then
if [[ -x $expanded_path ]]; then
if (( autocd )); then
if [[ -d $expanded_path ]]; then
REPLY=autodirectory
fi
return 0
elif [[ ! -d $expanded_path ]]; then
# ### This seems unreachable for the current callers
return 0
fi fi
fi
else
if [[ -L $expanded_path || -e $expanded_path ]]; then
return 0 return 0
fi fi
done
fi
# If dirname($1) doesn't exist, neither does $1.
[[ ! -d ${expanded_path:h} ]] && return 1
# If this word ends the buffer, check if it's the prefix of a valid path.
if (( has_end && (len == end_pos) )) &&
(( ! in_alias )) &&
[[ $WIDGET != zle-line-finish ]]; then
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
local -a tmp
if (( in_command_position )); then
# We include directories even when autocd is enabled, because those
# directories might contain executable files: e.g., BUFFER="/bi" en route
# to typing "/bin/sh".
tmp=( ${expanded_path}*(N-*,N-/) )
else
tmp=( ${expanded_path}*(N) )
fi fi
(( ${+tmp[1]} )) && REPLY=path_prefix && return 0
fi
# It's not a path. # Search the path in CDPATH
return 1 if [[ $expanded_path != /* ]] && (( autocd || ! in_command_position )); then
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
local cdpath_dir
for cdpath_dir in $cdpath ; do
if [[ -d "$cdpath_dir/$expanded_path" && -x "$cdpath_dir/$expanded_path" ]]; then
if (( in_command_position && autocd )); then
REPLY=autodirectory
fi
return 0
fi
done
fi
# If dirname($1) doesn't exist, neither does $1.
[[ ! -d ${expanded_path:h} ]] && return 1
# If this word ends the buffer, check if it's the prefix of a valid path.
if (( has_end && (len == end_pos) )) &&
(( ! in_alias )) &&
[[ $WIDGET != zle-line-finish ]]; then
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
local -a tmp
if (( in_command_position )); then
# We include directories even when autocd is enabled, because those
# directories might contain executable files: e.g., BUFFER="/bi" en route
# to typing "/bin/sh".
tmp=( ${expanded_path}*(N-*,N-/) )
else
tmp=( ${expanded_path}*(N) )
fi
(( ${+tmp[1]} )) && REPLY=path_prefix && return 0
fi
# It's not a path.
return 1
} always {
local -i ret=$((!!$?))
if (( $+_zsh_highlight_main__path_cache )); then
_zsh_highlight_main__path_cache[$cache_key]=$ret$REPLY
fi
}
} }
# Highlight an argument and possibly special chars in quotes starting at $1 in $arg # Highlight an argument and possibly special chars in quotes starting at $1 in $arg
@ -1809,15 +1828,16 @@ _zsh_highlight_main__precmd_hook() {
fi fi
_zsh_highlight_main__command_type_cache=() _zsh_highlight_main__command_type_cache=()
_zsh_highlight_main__path_cache=()
} }
autoload -Uz add-zsh-hook autoload -Uz add-zsh-hook
if add-zsh-hook precmd _zsh_highlight_main__precmd_hook 2>/dev/null; then if add-zsh-hook precmd _zsh_highlight_main__precmd_hook 2>/dev/null; then
# Initialize command type cache # Initialize caches
typeset -gA _zsh_highlight_main__command_type_cache typeset -gA _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache
else else
print -r -- >&2 'zsh-syntax-highlighting: Failed to load add-zsh-hook. Some speed optimizations will not be used.' print -r -- >&2 'zsh-syntax-highlighting: Failed to load add-zsh-hook. Some speed optimizations will not be used.'
# Make sure the cache is unset # Make sure the caches are unset
unset _zsh_highlight_main__command_type_cache unset _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache
fi fi
typeset -ga ZSH_HIGHLIGHT_DIRS_BLACKLIST typeset -ga ZSH_HIGHLIGHT_DIRS_BLACKLIST