36
36
: ${ZSH_HIGHLIGHT_STYLES[global-alias]:= fg=cyan}
37
37
: ${ZSH_HIGHLIGHT_STYLES[precommand]:= fg=green,underline}
38
38
: ${ZSH_HIGHLIGHT_STYLES[commandseparator]:= none}
39
+ : ${ZSH_HIGHLIGHT_STYLES[autodirectory]:= fg=green,underline}
39
40
: ${ZSH_HIGHLIGHT_STYLES[path]:= underline}
40
41
: ${ZSH_HIGHLIGHT_STYLES[path_pathseparator]:= }
41
42
: ${ZSH_HIGHLIGHT_STYLES[path_prefix_pathseparator]:= }
@@ -113,6 +114,7 @@ _zsh_highlight_main_calculate_fallback() {
113
114
command arg0
114
115
precommand arg0
115
116
hashed-command arg0
117
+ autodirectory arg0
116
118
arg0_\* arg0
117
119
118
120
# TODO: Maybe these? —
@@ -1016,7 +1018,7 @@ _zsh_highlight_main_highlighter_highlight_list()
1016
1018
fi
1017
1019
_zsh_highlight_main__stack_pop ' R' reserved-word
1018
1020
else
1019
- if _zsh_highlight_main_highlighter_check_path $arg ; then
1021
+ if _zsh_highlight_main_highlighter_check_path $arg 1 ; then
1020
1022
style=$REPLY
1021
1023
else
1022
1024
style=unknown-token
@@ -1125,12 +1127,27 @@ _zsh_highlight_main_highlighter_highlight_path_separators()
1125
1127
# Check if $1 is a path.
1126
1128
# If yes, return 0 and in $REPLY the style to use.
1127
1129
# Else, return non-zero (and the contents of $REPLY is undefined).
1130
+ #
1131
+ # $2 should be non-zero iff we're in command position.
1128
1132
_zsh_highlight_main_highlighter_check_path ()
1129
1133
{
1130
1134
_zsh_highlight_main_highlighter_expand_path " $1 "
1131
1135
local expanded_path=" $REPLY " tmp_path
1136
+ integer in_command_position=$2
1132
1137
1133
- REPLY=path
1138
+ if [[ $zsyh_user_options [autocd] == on ]]; then
1139
+ integer autocd=1
1140
+ else
1141
+ integer autocd=0
1142
+ fi
1143
+
1144
+ if (( in_command_position )) ; then
1145
+ # ### Currently, this value is never returned: either it's overwritten
1146
+ # ### below, or the return code is non-zero
1147
+ REPLY=arg0
1148
+ else
1149
+ REPLY=path
1150
+ fi
1134
1151
1135
1152
if [[ ${1[1]} == ' =' && $1 == ??* && ${1[2]} != $' \x28 ' && $zsyh_user_options [equals] == ' on' && $expanded_path [1] != ' /' ]]; then
1136
1153
REPLY=unknown-token # will error out if executed
@@ -1152,15 +1169,35 @@ _zsh_highlight_main_highlighter_check_path()
1152
1169
tmp_path=$tmp_path :h
1153
1170
done
1154
1171
1155
- [[ -L $expanded_path ]] && return 0
1156
- [[ -e $expanded_path ]] && return 0
1172
+ if (( in_command_position )) ; then
1173
+ if [[ -x $expanded_path ]]; then
1174
+ if (( autocd )) ; then
1175
+ if [[ -d $expanded_path ]]; then
1176
+ REPLY=autodirectory
1177
+ fi
1178
+ return 0
1179
+ elif [[ ! -d $expanded_path ]]; then
1180
+ # ### This seems unreachable for the current callers
1181
+ return 0
1182
+ fi
1183
+ fi
1184
+ else
1185
+ if [[ -L $expanded_path || -e $expanded_path ]]; then
1186
+ return 0
1187
+ fi
1188
+ fi
1157
1189
1158
1190
# Search the path in CDPATH
1159
- if [[ $expanded_path != /* ]]; then
1160
- local cdpath_dir
1191
+ if [[ $expanded_path != /* ]] && (( autocd || ! in_command_position )) ; then
1161
1192
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
1193
+ local cdpath_dir
1162
1194
for cdpath_dir in $cdpath ; do
1163
- [[ -e " $cdpath_dir /$expanded_path " ]] && return 0
1195
+ if [[ -d " $cdpath_dir /$expanded_path " && -x " $cdpath_dir /$expanded_path " ]]; then
1196
+ if (( in_command_position && autocd )) ; then
1197
+ REPLY=autodirectory
1198
+ fi
1199
+ return 0
1200
+ fi
1164
1201
done
1165
1202
fi
1166
1203
@@ -1169,10 +1206,18 @@ _zsh_highlight_main_highlighter_check_path()
1169
1206
1170
1207
# If this word ends the buffer, check if it's the prefix of a valid path.
1171
1208
if (( has_end && (len == end_pos) )) &&
1209
+ (( ! in_alias )) &&
1172
1210
[[ $WIDGET != zle-line-finish ]]; then
1173
1211
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
1174
1212
local -a tmp
1175
- tmp=( ${expanded_path} * (N) )
1213
+ if (( in_command_position )) ; then
1214
+ # We include directories even when autocd is enabled, because those
1215
+ # directories might contain executable files: e.g., BUFFER="/bi" en route
1216
+ # to typing "/bin/sh".
1217
+ tmp=( ${expanded_path} * (N-* ,N-/) )
1218
+ else
1219
+ tmp=( ${expanded_path} * (N) )
1220
+ fi
1176
1221
(( ${+tmp[1]} )) && REPLY=path_prefix && return 0
1177
1222
fi
1178
1223
@@ -1183,6 +1228,8 @@ _zsh_highlight_main_highlighter_check_path()
1183
1228
# Highlight an argument and possibly special chars in quotes starting at $1 in $arg
1184
1229
# This command will at least highlight $1 to end_pos with the default style
1185
1230
# If $2 is set to 0, the argument cannot be highlighted as an option.
1231
+ #
1232
+ # This function currently assumes it's never called for the command word.
1186
1233
_zsh_highlight_main_highlighter_highlight_argument ()
1187
1234
{
1188
1235
local base_style=default i=$1 option_eligible=${2:- 1} path_eligible=1 ret start style
@@ -1317,7 +1364,8 @@ _zsh_highlight_main_highlighter_highlight_argument()
1317
1364
else
1318
1365
base_style=numeric-fd
1319
1366
fi
1320
- elif _zsh_highlight_main_highlighter_check_path $arg [$1 ,-1]; then
1367
+ # This function is currently never called for the command word, so $2 is hard-coded as 0.
1368
+ elif _zsh_highlight_main_highlighter_check_path $arg [$1 ,-1] 0; then
1321
1369
base_style=$REPLY
1322
1370
_zsh_highlight_main_highlighter_highlight_path_separators $base_style
1323
1371
highlights+=($reply )
0 commit comments