Skip to content

Commit 6a210f1

Browse files
committed
Perf: fix several corner cases in command higlighting
1 parent e0d5921 commit 6a210f1

File tree

9 files changed

+188
-19
lines changed

9 files changed

+188
-19
lines changed

highlighters/main/main-highlighter.zsh

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ _zsh_highlight_main__type() {
147147
# ### $aliases_allowed, on the assumption that aliases are the common case.
148148
integer may_cache=1
149149

150+
local cmd
151+
150152
# Main logic
151153
unset REPLY
152154
if zmodload -e zsh/parameter; then
@@ -165,22 +167,29 @@ _zsh_highlight_main__type() {
165167
REPLY=function
166168
elif (( $+builtins[$1] )); then
167169
REPLY=builtin
168-
elif (( $+commands[$1] )); then
169-
REPLY=command
170+
elif [[ $1 != */* && -x ${cmd::=${commands[$1]-}} ]]; then
171+
# There is one case where the following logic incorrectly sets REPLY=command
172+
# instead of REPLY=hashed.
173+
#
174+
# % hash zsh=$commands[zsh]
175+
# % zsh # <-- here the type of `zsh` is "command" rather than "hashed"
176+
if [[ $cmd == /(|*/)$1 && $path[(Ie)${cmd:h}] != 0 ]]; then
177+
REPLY=command
178+
else
179+
REPLY=hashed
180+
fi
170181
# ZSH_VERSION >= 5.1 allows the use of #q. ZSH_VERSION <= 5.8 allows skipping
171182
# 'type -w' calls that are necessary for forward compatibility.
172183
elif [[ $ZSH_VERSION == 5.<1-8>(|.*) ]]; then
173-
if [[ $1 == */* && -n $1(#qN-.*) ||
174-
$1 == [^/]*/* && $zsyh_user_options[pathdirs] == on && -n ${^path}/$1(#q-N.*) ]]; then
175-
REPLY=command
176-
elif (( _zsh_highlight_main__rehash )); then
177-
builtin rehash
178-
_zsh_highlight_main__rehash=0
179-
if (( $+commands[$1] )); then
184+
if [[ $1 == */* ]]; then
185+
if [[ -n $1(#q-.*N) ||
186+
$1 != /* && $zsyh_user_options[pathdirs] == on && -n ${^path}/$1(#q-.*N) ]]; then
180187
REPLY=command
181188
else
182189
REPLY=none
183190
fi
191+
elif [[ -n ${^path}/$1(#q-.*N) ]]; then
192+
REPLY=command
184193
else
185194
REPLY=none
186195
fi
@@ -198,6 +207,8 @@ _zsh_highlight_main__type() {
198207
LC_ALL=C builtin type -w -- "$1" 2>/dev/null)##*: }:-none}"
199208
if [[ $REPLY == 'alias' ]]; then
200209
may_cache=0
210+
elif [[ $REPLY == 'hashed' && ( -n $cmd || $1 == */* ) ]]; then
211+
REPLY=none
201212
fi
202213
fi
203214

@@ -1752,8 +1763,6 @@ _zsh_highlight_main__precmd_hook() {
17521763
_zsh_highlight_main__path_cache=()
17531764
_zsh_highlight_main__arg_cache=()
17541765

1755-
_zsh_highlight_main__rehash=1
1756-
17571766
if [[ $ZSH_VERSION != (5.<9->*|<6->.*) ]]; then
17581767
_zsh_highlight_main_calculate_styles
17591768
fi
@@ -1763,12 +1772,10 @@ autoload -Uz add-zsh-hook
17631772
if add-zsh-hook precmd _zsh_highlight_main__precmd_hook 2>/dev/null; then
17641773
# Initialize caches
17651774
typeset -gA _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache _zsh_highlight_main__arg_cache
1766-
typeset -gi _zsh_highlight_main__rehash=1
17671775
else
17681776
print -r -- >&2 'zsh-syntax-highlighting: Failed to load add-zsh-hook. Some speed optimizations will not be used.'
17691777
# Make sure the caches are unset
17701778
unset _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache _zsh_highlight_main__arg_cache
1771-
unset _zsh_highlight_main__rehash
17721779
fi
17731780
typeset -ga ZSH_HIGHLIGHT_DIRS_BLACKLIST
17741781

@@ -1874,4 +1881,3 @@ _zsh_highlight_main__fallback_of=(
18741881
process-substitution{-delimiter,}
18751882
back-quoted-argument{-delimiter,}
18761883
)
1877-

highlighters/main/test-data/hashed-command.zsh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
# vim: ft=zsh sw=2 ts=2 et
2828
# -------------------------------------------------------------------------------------------------
2929

30-
hash zsh_syntax_highlighting_hash=/doesnotexist
30+
hash zsh_syntax_highlighting_hash=/usr/bin/env
3131
BUFFER='zsh_syntax_highlighting_hash'
3232

3333
expected_region_highlight=(
34-
"1 28 hashed-command 'zsh/parameter cannot distinguish between hashed and command'"
34+
"1 28 hashed-command"
3535
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -------------------------------------------------------------------------------------------------
2+
# Copyright (c) 2020 zsh-syntax-highlighting contributors
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without modification, are permitted
6+
# provided that the following conditions are met:
7+
#
8+
# * Redistributions of source code must retain the above copyright notice, this list of conditions
9+
# and the following disclaimer.
10+
# * Redistributions in binary form must reproduce the above copyright notice, this list of
11+
# conditions and the following disclaimer in the documentation and/or other materials provided
12+
# with the distribution.
13+
# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
14+
# may be used to endorse or promote products derived from this software without specific prior
15+
# written permission.
16+
#
17+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19+
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
# -------------------------------------------------------------------------------------------------
26+
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
27+
# vim: ft=zsh sw=2 ts=2 et
28+
# -------------------------------------------------------------------------------------------------
29+
30+
hash zsyh-hashed-command=/doesnotexist
31+
BUFFER='zsyh-hashed-command'
32+
33+
expected_region_highlight=(
34+
"1 19 unknown-token"
35+
)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# -------------------------------------------------------------------------------------------------
2+
# Copyright (c) 2020 zsh-syntax-highlighting contributors
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without modification, are permitted
6+
# provided that the following conditions are met:
7+
#
8+
# * Redistributions of source code must retain the above copyright notice, this list of conditions
9+
# and the following disclaimer.
10+
# * Redistributions in binary form must reproduce the above copyright notice, this list of
11+
# conditions and the following disclaimer in the documentation and/or other materials provided
12+
# with the distribution.
13+
# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
14+
# may be used to endorse or promote products derived from this software without specific prior
15+
# written permission.
16+
#
17+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19+
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
# -------------------------------------------------------------------------------------------------
26+
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
27+
# vim: ft=zsh sw=2 ts=2 et
28+
# -------------------------------------------------------------------------------------------------
29+
30+
hash zsyh-hashed-command=/usr/bin/env
31+
BUFFER='doesnotexist; zsyh-hashed-command'
32+
33+
expected_region_highlight=(
34+
"1 12 unknown-token"
35+
"13 13 commandseparator"
36+
"15 33 hashed-command"
37+
)

highlighters/main/test-data/precommand-killing1.zsh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# vim: ft=zsh sw=2 ts=2 et
2929
# -------------------------------------------------------------------------------------------------
3030

31-
hash sudo=false
31+
hash sudo=/usr/bin/env
3232
touch foo
3333

3434
BUFFER='sudo -e ./foo'

highlighters/main/test-data/precommand-killing2.zsh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# vim: ft=zsh sw=2 ts=2 et
2929
# -------------------------------------------------------------------------------------------------
3030

31-
hash sudo=false
31+
hash sudo=/usr/bin/env
3232

3333
BUFFER='sudo -e /does/not/exist'
3434

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -------------------------------------------------------------------------------------------------
2+
# Copyright (c) 2020 zsh-syntax-highlighting contributors
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without modification, are permitted
6+
# provided that the following conditions are met:
7+
#
8+
# * Redistributions of source code must retain the above copyright notice, this list of conditions
9+
# and the following disclaimer.
10+
# * Redistributions in binary form must reproduce the above copyright notice, this list of
11+
# conditions and the following disclaimer in the documentation and/or other materials provided
12+
# with the distribution.
13+
# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
14+
# may be used to endorse or promote products derived from this software without specific prior
15+
# written permission.
16+
#
17+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19+
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
# -------------------------------------------------------------------------------------------------
26+
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
27+
# vim: ft=zsh sw=2 ts=2 et
28+
# -------------------------------------------------------------------------------------------------
29+
30+
if [[ $OSTYPE == msys ]]; then
31+
skip_test='Cannot chmod +x in msys2'
32+
else
33+
mkdir foo
34+
print >foo/bar
35+
chmod +x foo/bar
36+
hash zsyh-hashed-command=foo/bar
37+
hash subdir/zsyh-hashed-command=foo/bar
38+
39+
BUFFER='zsyh-hashed-command; subdir/zsyh-hashed-command'
40+
41+
expected_region_highlight=(
42+
"1 19 hashed-command"
43+
"20 20 commandseparator"
44+
"22 47 unknown-token"
45+
)
46+
fi
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# -------------------------------------------------------------------------------------------------
2+
# Copyright (c) 2020 zsh-syntax-highlighting contributors
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without modification, are permitted
6+
# provided that the following conditions are met:
7+
#
8+
# * Redistributions of source code must retain the above copyright notice, this list of conditions
9+
# and the following disclaimer.
10+
# * Redistributions in binary form must reproduce the above copyright notice, this list of
11+
# conditions and the following disclaimer in the documentation and/or other materials provided
12+
# with the distribution.
13+
# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors
14+
# may be used to endorse or promote products derived from this software without specific prior
15+
# written permission.
16+
#
17+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
18+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19+
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
# -------------------------------------------------------------------------------------------------
26+
# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
27+
# vim: ft=zsh sw=2 ts=2 et
28+
# -------------------------------------------------------------------------------------------------
29+
30+
if [[ $OSTYPE == msys ]]; then
31+
skip_test='Cannot chmod +x in msys2'
32+
else
33+
mkdir foo
34+
print >foo/zsyh-new-command
35+
chmod +x foo/zsyh-new-command
36+
path+=($PWD/foo)
37+
: $+commands[zsyh-new-command]
38+
rm foo/zsyh-new-command
39+
40+
BUFFER='zsyh-new-command'
41+
42+
expected_region_highlight=(
43+
"1 16 unknown-token"
44+
)
45+
fi

highlighters/main/test-data/sudo-longopt.zsh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# vim: ft=zsh sw=2 ts=2 et
2929
# -------------------------------------------------------------------------------------------------
3030

31-
hash sudo='false'
31+
hash sudo=/usr/bin/env
3232
BUFFER='sudo --askpass ls'
3333

3434
expected_region_highlight=(

0 commit comments

Comments
 (0)