From 1d76c0be32db1ce5bd389a5194d73cc28a652441 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Mar 2020 02:01:17 +0000 Subject: [PATCH 1/6] tests: Add a test for issue #701, concerning escaped reserved words. --- .../test-data/escaped-reserved-word-isnt.zsh | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 highlighters/main/test-data/escaped-reserved-word-isnt.zsh 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..97c26aa --- /dev/null +++ b/highlighters/main/test-data/escaped-reserved-word-isnt.zsh @@ -0,0 +1,35 @@ +#!/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 "issue #701"' # \\local +) From f284041305d0ccb0ba5d3ce5af7ade36d7bbc7e9 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Mar 2020 02:11:37 +0000 Subject: [PATCH 2/6] 'main': Check cheaper conditions first. --- highlighters/main/main-highlighter.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index dbb0df9..c9ba63b 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -180,9 +180,9 @@ _zsh_highlight_main__type() { 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' From 39977391def0ab8260fc76a9e2c98c0bece8ef9b Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Mar 2020 02:12:00 +0000 Subject: [PATCH 3/6] 'main': Highlight escaped reserved words properly. Fixes #701. --- highlighters/main/main-highlighter.zsh | 9 ++++++--- .../main/test-data/escaped-reserved-word-isnt.zsh | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index c9ba63b..fc12366 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -153,9 +153,12 @@ _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} + integer -r resword_allowed=${3-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. # @@ -186,7 +189,7 @@ _zsh_highlight_main__type() { 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 @@ -616,7 +619,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,7 +651,7 @@ _zsh_highlight_main_highlighter_highlight_list() continue else _zsh_highlight_main_highlighter_expand_path $arg - _zsh_highlight_main__type "$REPLY" 0 + _zsh_highlight_main__type "$REPLY" 0 0 res="$REPLY" fi fi diff --git a/highlighters/main/test-data/escaped-reserved-word-isnt.zsh b/highlighters/main/test-data/escaped-reserved-word-isnt.zsh index 97c26aa..14e335b 100644 --- a/highlighters/main/test-data/escaped-reserved-word-isnt.zsh +++ b/highlighters/main/test-data/escaped-reserved-word-isnt.zsh @@ -31,5 +31,7 @@ BUFFER=$'\\local a=( * )' expected_region_highlight=( - '1 6 builtin "issue #701"' # \\local + '1 6 builtin' # \\local + '8 14 default' # a=( * ) + '12 12 globbing' # * ) From e0d1bc5c86e22ba35f98371b1ad88e9f136ad87b Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Mar 2020 02:12:43 +0000 Subject: [PATCH 4/6] changelog: Update through HEAD. --- changelog.md | 3 +++ 1 file changed, 3 insertions(+) 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. From c27470a08da6b133679c091e699070f53b3b8c7c Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Mar 2020 02:17:11 +0000 Subject: [PATCH 5/6] 'main': Let aliases be type-cached, and don't run type-checking twice (with slightly different settings) if path expansion returned the input unchanged. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In particular, note that applying all but the last hunk of this diff would cause «time» in command position to be highlighted as «command» rather than «reserved». (This is covered by tests.) --- highlighters/main/main-highlighter.zsh | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index fc12366..7333631 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -159,16 +159,11 @@ _zsh_highlight_main_calculate_fallback() { _zsh_highlight_main__type() { integer -r aliases_allowed=${2-1} integer -r resword_allowed=${3-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 + 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 @@ -180,9 +175,6 @@ _zsh_highlight_main__type() { fi unset REPLY if zmodload -e zsh/parameter; then - if (( $+aliases[(e)$1] )); then - may_cache=0 - fi if (( aliases_allowed )) && (( ${+galiases[(e)$1]} )); then REPLY='global alias' elif (( aliases_allowed )) && (( $+aliases[(e)$1] )) &&; then @@ -226,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 $? @@ -651,8 +640,10 @@ _zsh_highlight_main_highlighter_highlight_list() continue else _zsh_highlight_main_highlighter_expand_path $arg - _zsh_highlight_main__type "$REPLY" 0 0 - res="$REPLY" + if [[ $arg != $REPLY ]]; then + _zsh_highlight_main__type "$REPLY" 0 0 + res="$REPLY" + fi fi fi From 5fd2ae8981620a7d72628fc92b98a468c8298a89 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Tue, 17 Mar 2020 02:21:08 +0000 Subject: [PATCH 6/6] 'main': Add TODO. --- highlighters/main/main-highlighter.zsh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh index 7333631..0c3d45a 100644 --- a/highlighters/main/main-highlighter.zsh +++ b/highlighters/main/main-highlighter.zsh @@ -641,6 +641,9 @@ _zsh_highlight_main_highlighter_highlight_list() else _zsh_highlight_main_highlighter_expand_path $arg 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