Skip to content

Commit d944106

Browse files
committed
Perf: memoize _zsh_highlight_main_highlighter_check_path
1 parent 6d5372a commit d944106

File tree

1 file changed

+100
-80
lines changed

1 file changed

+100
-80
lines changed

highlighters/main/main-highlighter.zsh

Lines changed: 100 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,98 +1182,117 @@ _zsh_highlight_main_highlighter_highlight_path_separators()
11821182
# $2 should be non-zero iff we're in command position.
11831183
_zsh_highlight_main_highlighter_check_path()
11841184
{
1185-
_zsh_highlight_main_highlighter_expand_path "$1"
1186-
local expanded_path="$REPLY" tmp_path
1187-
integer in_command_position=$2
1188-
1189-
if [[ $zsyh_user_options[autocd] == on ]]; then
1190-
integer autocd=1
1191-
else
1192-
integer autocd=0
1185+
if (( $+_zsh_highlight_main__path_cache )); then
1186+
local cache_key=$1$'\0'$2
1187+
if (( has_end && len == end_pos && !in_alias )) && [[ $WIDGET != zle-line-finish ]]; then
1188+
cache_key+=$'\0'
1189+
fi
1190+
local cache_val=$_zsh_highlight_main__path_cache[$cache_key]
1191+
if [[ -n $cache_val ]]; then
1192+
REPLY=${cache_val:1}
1193+
return $cache_val[1]
1194+
fi
11931195
fi
11941196

1195-
if (( in_command_position )); then
1196-
# ### Currently, this value is never returned: either it's overwritten
1197-
# ### below, or the return code is non-zero
1198-
REPLY=arg0
1199-
else
1200-
REPLY=path
1201-
fi
1197+
{
1198+
_zsh_highlight_main_highlighter_expand_path "$1"
1199+
local expanded_path="$REPLY" tmp_path
1200+
integer in_command_position=$2
12021201

1203-
if [[ ${1[1]} == '=' && $1 == ??* && ${1[2]} != $'\x28' && $zsyh_user_options[equals] == 'on' && $expanded_path[1] != '/' ]]; then
1204-
REPLY=unknown-token # will error out if executed
1205-
return 0
1206-
fi
1202+
if [[ $zsyh_user_options[autocd] == on ]]; then
1203+
integer autocd=1
1204+
else
1205+
integer autocd=0
1206+
fi
12071207

1208-
[[ -z $expanded_path ]] && return 1
1208+
if (( in_command_position )); then
1209+
# ### Currently, this value is never returned: either it's overwritten
1210+
# ### below, or the return code is non-zero
1211+
REPLY=arg0
1212+
else
1213+
REPLY=path
1214+
fi
12091215

1210-
# Check if this is a blacklisted path
1211-
if [[ $expanded_path[1] == / ]]; then
1212-
tmp_path=$expanded_path
1213-
else
1214-
tmp_path=$PWD/$expanded_path
1215-
fi
1216-
tmp_path=$tmp_path:a
1216+
if [[ ${1[1]} == '=' && $1 == ??* && ${1[2]} != $'\x28' && $zsyh_user_options[equals] == 'on' && $expanded_path[1] != '/' ]]; then
1217+
REPLY=unknown-token # will error out if executed
1218+
return 0
1219+
fi
12171220

1218-
while [[ $tmp_path != / ]]; do
1219-
[[ -n ${(M)ZSH_HIGHLIGHT_DIRS_BLACKLIST:#$tmp_path} ]] && return 1
1220-
tmp_path=$tmp_path:h
1221-
done
1221+
[[ -z $expanded_path ]] && return 1
12221222

1223-
if (( in_command_position )); then
1224-
if [[ -x $expanded_path ]]; then
1225-
if (( autocd )); then
1226-
if [[ -d $expanded_path ]]; then
1227-
REPLY=autodirectory
1228-
fi
1229-
return 0
1230-
elif [[ ! -d $expanded_path ]]; then
1231-
# ### This seems unreachable for the current callers
1232-
return 0
1233-
fi
1234-
fi
1235-
else
1236-
if [[ -L $expanded_path || -e $expanded_path ]]; then
1237-
return 0
1223+
# Check if this is a blacklisted path
1224+
if [[ $expanded_path[1] == / ]]; then
1225+
tmp_path=$expanded_path
1226+
else
1227+
tmp_path=$PWD/$expanded_path
12381228
fi
1239-
fi
1229+
tmp_path=$tmp_path:a
1230+
1231+
while [[ $tmp_path != / ]]; do
1232+
[[ -n ${(M)ZSH_HIGHLIGHT_DIRS_BLACKLIST:#$tmp_path} ]] && return 1
1233+
tmp_path=$tmp_path:h
1234+
done
12401235

1241-
# Search the path in CDPATH
1242-
if [[ $expanded_path != /* ]] && (( autocd || ! in_command_position )); then
1243-
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
1244-
local cdpath_dir
1245-
for cdpath_dir in $cdpath ; do
1246-
if [[ -d "$cdpath_dir/$expanded_path" && -x "$cdpath_dir/$expanded_path" ]]; then
1247-
if (( in_command_position && autocd )); then
1248-
REPLY=autodirectory
1236+
if (( in_command_position )); then
1237+
if [[ -x $expanded_path ]]; then
1238+
if (( autocd )); then
1239+
if [[ -d $expanded_path ]]; then
1240+
REPLY=autodirectory
1241+
fi
1242+
return 0
1243+
elif [[ ! -d $expanded_path ]]; then
1244+
# ### This seems unreachable for the current callers
1245+
return 0
12491246
fi
1247+
fi
1248+
else
1249+
if [[ -L $expanded_path || -e $expanded_path ]]; then
12501250
return 0
12511251
fi
1252-
done
1253-
fi
1252+
fi
12541253

1255-
# If dirname($1) doesn't exist, neither does $1.
1256-
[[ ! -d ${expanded_path:h} ]] && return 1
1254+
# Search the path in CDPATH
1255+
if [[ $expanded_path != /* ]] && (( autocd || ! in_command_position )); then
1256+
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
1257+
local cdpath_dir
1258+
for cdpath_dir in $cdpath ; do
1259+
if [[ -d "$cdpath_dir/$expanded_path" && -x "$cdpath_dir/$expanded_path" ]]; then
1260+
if (( in_command_position && autocd )); then
1261+
REPLY=autodirectory
1262+
fi
1263+
return 0
1264+
fi
1265+
done
1266+
fi
12571267

1258-
# If this word ends the buffer, check if it's the prefix of a valid path.
1259-
if (( has_end && (len == end_pos) )) &&
1260-
(( ! in_alias )) &&
1261-
[[ $WIDGET != zle-line-finish ]]; then
1262-
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
1263-
local -a tmp
1264-
if (( in_command_position )); then
1265-
# We include directories even when autocd is enabled, because those
1266-
# directories might contain executable files: e.g., BUFFER="/bi" en route
1267-
# to typing "/bin/sh".
1268-
tmp=( ${expanded_path}*(N-*,N-/) )
1269-
else
1270-
tmp=( ${expanded_path}*(N) )
1268+
# If dirname($1) doesn't exist, neither does $1.
1269+
[[ ! -d ${expanded_path:h} ]] && return 1
1270+
1271+
# If this word ends the buffer, check if it's the prefix of a valid path.
1272+
if (( has_end && (len == end_pos) )) &&
1273+
(( ! in_alias )) &&
1274+
[[ $WIDGET != zle-line-finish ]]; then
1275+
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
1276+
local -a tmp
1277+
if (( in_command_position )); then
1278+
# We include directories even when autocd is enabled, because those
1279+
# directories might contain executable files: e.g., BUFFER="/bi" en route
1280+
# to typing "/bin/sh".
1281+
tmp=( ${expanded_path}*(N-*,N-/) )
1282+
else
1283+
tmp=( ${expanded_path}*(N) )
1284+
fi
1285+
(( ${+tmp[1]} )) && REPLY=path_prefix && return 0
12711286
fi
1272-
(( ${+tmp[1]} )) && REPLY=path_prefix && return 0
1273-
fi
12741287

1275-
# It's not a path.
1276-
return 1
1288+
# It's not a path.
1289+
return 1
1290+
} always {
1291+
local -i ret=$((!!$?))
1292+
if (( $+_zsh_highlight_main__path_cache )); then
1293+
_zsh_highlight_main__path_cache[$cache_key]=$ret$REPLY
1294+
fi
1295+
}
12771296
}
12781297

12791298
# Highlight an argument and possibly special chars in quotes starting at $1 in $arg
@@ -1809,15 +1828,16 @@ _zsh_highlight_main__precmd_hook() {
18091828
fi
18101829

18111830
_zsh_highlight_main__command_type_cache=()
1831+
_zsh_highlight_main__path_cache=()
18121832
}
18131833

18141834
autoload -Uz add-zsh-hook
18151835
if add-zsh-hook precmd _zsh_highlight_main__precmd_hook 2>/dev/null; then
1816-
# Initialize command type cache
1817-
typeset -gA _zsh_highlight_main__command_type_cache
1836+
# Initialize caches
1837+
typeset -gA _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache
18181838
else
18191839
print -r -- >&2 'zsh-syntax-highlighting: Failed to load add-zsh-hook. Some speed optimizations will not be used.'
1820-
# Make sure the cache is unset
1821-
unset _zsh_highlight_main__command_type_cache
1840+
# Make sure the caches are unset
1841+
unset _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache
18221842
fi
18231843
typeset -ga ZSH_HIGHLIGHT_DIRS_BLACKLIST

0 commit comments

Comments
 (0)