mirror of
https://github.com/zsh-users/zsh-syntax-highlighting.git
synced 2025-04-17 11:35:32 +08:00
Perf: memoize _zsh_highlight_main_highlighter_check_path
This commit is contained in:
parent
4cf464f843
commit
826aa7312d
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user