diff --git a/changelog.md b/changelog.md index 9e7c5a4..26d6fbe 100644 --- a/changelog.md +++ b/changelog.md @@ -57,6 +57,9 @@ - Highlight global aliases [#700] +- Fix highlighting of `\local`, `\typeset`, etc (escaped) + [#701] + # Changes in version 0.7.1 - Remove out-of-date information from the 0.7.0 changelog. diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index dbb0df9..0c3d45a 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -153,19 +153,17 @@ _zsh_highlight_main_calculate_fallback() { # # If $2 is 0, do not consider aliases. # +# If $3 is 0, do not consider reserved words. +# # The result will be stored in REPLY. _zsh_highlight_main__type() { integer -r aliases_allowed=${2-1} - # We won't cache replies of anything that exists as an alias at all, to - # ensure the cached value is correct regardless of $aliases_allowed. - # - # ### We probably _should_ cache them in a cache that's keyed on the value of - # ### $aliases_allowed, on the assumption that aliases are the common case. - integer may_cache=1 + integer -r resword_allowed=${3-1} + readonly cache_key="${1}:$(( aliases_allowed ? 1 : 0)):$((resword_allowed ? 1 : 0))" # Cache lookup if (( $+_zsh_highlight_main__command_type_cache )); then - REPLY=$_zsh_highlight_main__command_type_cache[(e)$1] + REPLY=$_zsh_highlight_main__command_type_cache[(e)$cache_key] if [[ -n "$REPLY" ]]; then return fi @@ -177,16 +175,13 @@ _zsh_highlight_main__type() { fi unset REPLY if zmodload -e zsh/parameter; then - if (( $+aliases[(e)$1] )); then - may_cache=0 - fi - if (( ${+galiases[(e)$1]} )) && (( aliases_allowed )); then + if (( aliases_allowed )) && (( ${+galiases[(e)$1]} )); then REPLY='global alias' - elif (( $+aliases[(e)$1] )) && (( aliases_allowed )); then + elif (( aliases_allowed )) && (( $+aliases[(e)$1] )) &&; then REPLY=alias elif [[ $1 == *.* && -n ${1%.*} ]] && (( $+saliases[(e)${1##*.}] )); then REPLY='suffix alias' - elif (( $reswords[(Ie)$1] )); then + elif (( resword_allowed )) && (( $reswords[(Ie)$1] )); then REPLY=reserved elif (( $+functions[(e)$1] )); then REPLY=function @@ -223,14 +218,11 @@ _zsh_highlight_main__type() { # «$(…)»], which is area that has had some parsing bugs before 5.6 # (approximately). REPLY="${$(:; (( aliases_allowed )) || unalias -- "$1" 2>/dev/null; LC_ALL=C builtin type -w -- "$1" 2>/dev/null)##*: }" - if [[ $REPLY == 'alias' ]]; then - may_cache=0 - fi fi # Cache population - if (( may_cache )) && (( $+_zsh_highlight_main__command_type_cache )); then - _zsh_highlight_main__command_type_cache[(e)$1]=$REPLY + if (( $+_zsh_highlight_main__command_type_cache )); then + _zsh_highlight_main__command_type_cache[(e)$cache_key]=$REPLY fi [[ -n $REPLY ]] return $? @@ -616,7 +608,7 @@ _zsh_highlight_main_highlighter_highlight_list() if [[ $this_word == *':start:'* ]] && ! (( in_redirection )); then # Expand aliases. # An alias is ineligible for expansion while it's being expanded (see #652/#653). - _zsh_highlight_main__type "$arg" "$(( ! ${+seen_alias[$arg]} ))" + _zsh_highlight_main__type "$arg" "$(( ! ${+seen_alias[$arg]} ))" 1 local res="$REPLY" if [[ $res == "alias" ]]; then # Mark insane aliases as unknown-token (cf. #263). @@ -648,8 +640,13 @@ _zsh_highlight_main_highlighter_highlight_list() continue else _zsh_highlight_main_highlighter_expand_path $arg - _zsh_highlight_main__type "$REPLY" 0 - res="$REPLY" + if [[ $arg != $REPLY ]]; then + # TODO: Is this right? Shouldn't we simply check whether it's + # executable? It's not just aliases and reserved words that aren't + # considered here; builtins should likewise be excluded. + _zsh_highlight_main__type "$REPLY" 0 0 + res="$REPLY" + fi fi fi diff --git a/highlighters/main/test-data/escaped-reserved-word-isnt.zsh b/highlighters/main/test-data/escaped-reserved-word-isnt.zsh new file mode 100644 index 0000000..14e335b --- /dev/null +++ b/highlighters/main/test-data/escaped-reserved-word-isnt.zsh @@ -0,0 +1,37 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# 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 +# ------------------------------------------------------------------------------------------------- + +BUFFER=$'\\local a=( * )' + +expected_region_highlight=( + '1 6 builtin' # \\local + '8 14 default' # a=( * ) + '12 12 globbing' # * +)