diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index fa8e32b..f738b6e 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -147,6 +147,8 @@ _zsh_highlight_main__type() { # ### $aliases_allowed, on the assumption that aliases are the common case. integer may_cache=1 + local cmd + # Main logic unset REPLY if zmodload -e zsh/parameter; then @@ -165,22 +167,29 @@ _zsh_highlight_main__type() { REPLY=function elif (( $+builtins[$1] )); then REPLY=builtin - elif (( $+commands[$1] )); then - REPLY=command + elif [[ $1 != */* && -x ${cmd::=${commands[$1]-}} ]]; then + # There is one case where the following logic incorrectly sets REPLY=command + # instead of REPLY=hashed. + # + # % hash zsh=$commands[zsh] + # % zsh # <-- here the type of `zsh` is "command" rather than "hashed" + if [[ $cmd == /(|*/)$1 && $path[(Ie)${cmd:h}] != 0 ]]; then + REPLY=command + else + REPLY=hashed + fi # ZSH_VERSION >= 5.1 allows the use of #q. ZSH_VERSION <= 5.8 allows skipping # 'type -w' calls that are necessary for forward compatibility. elif [[ $ZSH_VERSION == 5.<1-8>(|.*) ]]; then - if [[ $1 == */* && -n $1(#qN-.*) || - $1 == [^/]*/* && $zsyh_user_options[pathdirs] == on && -n ${^path}/$1(#q-N.*) ]]; then - REPLY=command - elif (( _zsh_highlight_main__rehash )); then - builtin rehash - _zsh_highlight_main__rehash=0 - if (( $+commands[$1] )); then + if [[ $1 == */* ]]; then + if [[ -n $1(#q-.*N) || + $1 != /* && $zsyh_user_options[pathdirs] == on && -n ${^path}/$1(#q-.*N) ]]; then REPLY=command else REPLY=none fi + elif [[ -n ${^path}/$1(#q-.*N) ]]; then + REPLY=command else REPLY=none fi @@ -198,6 +207,8 @@ _zsh_highlight_main__type() { LC_ALL=C builtin type -w -- "$1" 2>/dev/null)##*: }:-none}" if [[ $REPLY == 'alias' ]]; then may_cache=0 + elif [[ $REPLY == 'hashed' && ( -n $cmd || $1 == */* ) ]]; then + REPLY=none fi fi @@ -1752,8 +1763,6 @@ _zsh_highlight_main__precmd_hook() { _zsh_highlight_main__path_cache=() _zsh_highlight_main__arg_cache=() - _zsh_highlight_main__rehash=1 - if [[ $ZSH_VERSION != (5.<9->*|<6->.*) ]]; then _zsh_highlight_main_calculate_styles fi @@ -1763,12 +1772,10 @@ autoload -Uz add-zsh-hook if add-zsh-hook precmd _zsh_highlight_main__precmd_hook 2>/dev/null; then # Initialize caches typeset -gA _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache _zsh_highlight_main__arg_cache - typeset -gi _zsh_highlight_main__rehash=1 else print -r -- >&2 'zsh-syntax-highlighting: Failed to load add-zsh-hook. Some speed optimizations will not be used.' # Make sure the caches are unset unset _zsh_highlight_main__command_type_cache _zsh_highlight_main__path_cache _zsh_highlight_main__arg_cache - unset _zsh_highlight_main__rehash fi typeset -ga ZSH_HIGHLIGHT_DIRS_BLACKLIST @@ -1874,4 +1881,3 @@ _zsh_highlight_main__fallback_of=( process-substitution{-delimiter,} back-quoted-argument{-delimiter,} ) - diff --git a/highlighters/main/test-data/hashed-command.zsh b/highlighters/main/test-data/hashed-command.zsh index 2983ef8..35458b4 100644 --- a/highlighters/main/test-data/hashed-command.zsh +++ b/highlighters/main/test-data/hashed-command.zsh @@ -27,9 +27,9 @@ # vim: ft=zsh sw=2 ts=2 et # ------------------------------------------------------------------------------------------------- -hash zsh_syntax_highlighting_hash=/doesnotexist +hash zsh_syntax_highlighting_hash=/usr/bin/env BUFFER='zsh_syntax_highlighting_hash' expected_region_highlight=( - "1 28 hashed-command 'zsh/parameter cannot distinguish between hashed and command'" + "1 28 hashed-command" ) diff --git a/highlighters/main/test-data/invalid-hashed-command.zsh b/highlighters/main/test-data/invalid-hashed-command.zsh new file mode 100644 index 0000000..d29fc3e --- /dev/null +++ b/highlighters/main/test-data/invalid-hashed-command.zsh @@ -0,0 +1,35 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2020 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +hash zsyh-hashed-command=/doesnotexist +BUFFER='zsyh-hashed-command' + +expected_region_highlight=( + "1 19 unknown-token" +) diff --git a/highlighters/main/test-data/no-rehash.zsh b/highlighters/main/test-data/no-rehash.zsh new file mode 100644 index 0000000..13bf569 --- /dev/null +++ b/highlighters/main/test-data/no-rehash.zsh @@ -0,0 +1,37 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2020 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +hash zsyh-hashed-command=/usr/bin/env +BUFFER='doesnotexist; zsyh-hashed-command' + +expected_region_highlight=( + "1 12 unknown-token" + "13 13 commandseparator" + "15 33 hashed-command" +) diff --git a/highlighters/main/test-data/precommand-killing1.zsh b/highlighters/main/test-data/precommand-killing1.zsh index 7598346..abb5b88 100644 --- a/highlighters/main/test-data/precommand-killing1.zsh +++ b/highlighters/main/test-data/precommand-killing1.zsh @@ -28,7 +28,7 @@ # vim: ft=zsh sw=2 ts=2 et # ------------------------------------------------------------------------------------------------- -hash sudo=false +hash sudo=/usr/bin/env touch foo BUFFER='sudo -e ./foo' diff --git a/highlighters/main/test-data/precommand-killing2.zsh b/highlighters/main/test-data/precommand-killing2.zsh index bc6fc86..1f306ae 100644 --- a/highlighters/main/test-data/precommand-killing2.zsh +++ b/highlighters/main/test-data/precommand-killing2.zsh @@ -28,7 +28,7 @@ # vim: ft=zsh sw=2 ts=2 et # ------------------------------------------------------------------------------------------------- -hash sudo=false +hash sudo=/usr/bin/env BUFFER='sudo -e /does/not/exist' diff --git a/highlighters/main/test-data/relative-hashed-command.zsh b/highlighters/main/test-data/relative-hashed-command.zsh new file mode 100644 index 0000000..7993a0a --- /dev/null +++ b/highlighters/main/test-data/relative-hashed-command.zsh @@ -0,0 +1,46 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2020 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +if [[ $OSTYPE == msys ]]; then + skip_test='Cannot chmod +x in msys2' +else + mkdir foo + print >foo/bar + chmod +x foo/bar + hash zsyh-hashed-command=foo/bar + hash subdir/zsyh-hashed-command=foo/bar + + BUFFER='zsyh-hashed-command; subdir/zsyh-hashed-command' + + expected_region_highlight=( + "1 19 hashed-command" + "20 20 commandseparator" + "22 47 unknown-token" + ) +fi diff --git a/highlighters/main/test-data/removed-command.zsh b/highlighters/main/test-data/removed-command.zsh new file mode 100644 index 0000000..b28cde4 --- /dev/null +++ b/highlighters/main/test-data/removed-command.zsh @@ -0,0 +1,45 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2020 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +if [[ $OSTYPE == msys ]]; then + skip_test='Cannot chmod +x in msys2' +else + mkdir foo + print >foo/zsyh-new-command + chmod +x foo/zsyh-new-command + path+=($PWD/foo) + : $+commands[zsyh-new-command] + rm foo/zsyh-new-command + + BUFFER='zsyh-new-command' + + expected_region_highlight=( + "1 16 unknown-token" + ) +fi diff --git a/highlighters/main/test-data/sudo-longopt.zsh b/highlighters/main/test-data/sudo-longopt.zsh index ef768bf..612fcb1 100644 --- a/highlighters/main/test-data/sudo-longopt.zsh +++ b/highlighters/main/test-data/sudo-longopt.zsh @@ -28,7 +28,7 @@ # vim: ft=zsh sw=2 ts=2 et # ------------------------------------------------------------------------------------------------- -hash sudo='false' +hash sudo=/usr/bin/env BUFFER='sudo --askpass ls' expected_region_highlight=(