Skip to content

Alias fix #776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 35 additions & 22 deletions highlighters/main/main-highlighter.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ _zsh_highlight_main_add_region_highlight() {
integer start=$1 end=$2
shift 2

if (( in_alias )); then
if (( $#in_alias )); then
[[ $1 == unknown-token ]] && alias_style=unknown-token
return
fi
Expand Down Expand Up @@ -498,17 +498,18 @@ _zsh_highlight_main_highlighter__try_expand_parameter()
_zsh_highlight_main_highlighter_highlight_list()
{
integer start_pos end_pos=0 buf_offset=$1 has_end=$3
# alias_style is the style to apply to an alias once in_alias=0
# alias_style is the style to apply to an alias once $#in_alias == 0
# Usually 'alias' but set to 'unknown-token' if any word expanded from
# the alias would be highlighted as unknown-token
# param_style is analogous for parameter expansions
local alias_style param_style last_arg arg buf=$4 highlight_glob=true saw_assignment=false style
local in_array_assignment=false # true between 'a=(' and the matching ')'
# in_alias is equal to the number of shifts needed until arg=args[1] pops an
# arg from BUFFER and not added by an alias.
# in_alias is an array of integers with each element equal to the number
# of shifts needed until arg=args[1] pops an arg from the next level up
# alias or from BUFFER.
# in_param is analogous for parameter expansions
integer in_alias=0 in_param=0 len=$#buf
local -a match mbegin mend list_highlights
integer in_param=0 len=$#buf
local -a in_alias match mbegin mend list_highlights
# seen_alias is a map of aliases already seen to avoid loops like alias a=b b=a
local -A seen_alias
# Pattern for parameter names
Expand Down Expand Up @@ -596,9 +597,17 @@ _zsh_highlight_main_highlighter_highlight_list()
last_arg=$arg
arg=$args[1]
shift args
if (( in_alias )); then
(( in_alias-- ))
if (( in_alias == 0 )); then
if (( $#in_alias )); then
(( in_alias[1]-- ))
# Remove leading 0 entries
in_alias=($in_alias[$in_alias[(i)<1->],-1])
(){
local alias_name
for alias_name in ${(k)seen_alias[(R)<$#in_alias->]}; do
unset "seen_alias[$alias_name]"
done
}
if (( $#in_alias == 0 )); then
seen_alias=()
# start_pos and end_pos are of the alias (previous $arg) here
_zsh_highlight_main_add_region_highlight $start_pos $end_pos $alias_style
Expand Down Expand Up @@ -637,7 +646,7 @@ _zsh_highlight_main_highlighter_highlight_list()
fi
fi

if (( in_alias == 0 && in_param == 0 )); then
if (( $#in_alias == 0 && in_param == 0 )); then
# Compute the new $start_pos and $end_pos, skipping over whitespace in $buf.
[[ "$proc_buf" = (#b)(#s)(([ $'\t']|[\\]$'\n')#)(?|)* ]]
# The first, outer parenthesis
Expand Down Expand Up @@ -693,11 +702,10 @@ _zsh_highlight_main_highlighter_highlight_list()
if [[ $res == "alias" ]]; then
# Mark insane aliases as unknown-token (cf. #263).
if [[ $arg == ?*=* ]]; then
(( in_alias == 0 )) && in_alias=1
_zsh_highlight_main_add_region_highlight $start_pos $end_pos unknown-token
continue
fi
seen_alias[$arg]=1
seen_alias[$arg]=$#in_alias
_zsh_highlight_main__resolve_alias $arg
local -a alias_args
# Elision is desired in case alias x=''
Expand All @@ -707,15 +715,15 @@ _zsh_highlight_main_highlighter_highlight_list()
alias_args=(${(z)REPLY})
fi
args=( $alias_args $args )
if (( in_alias == 0 )); then
if (( $#in_alias == 0 )); then
alias_style=alias
# Add one because we will in_alias-- on the next loop iteration so
# this iteration should be considered in in_alias as well
(( in_alias += $#alias_args + 1 ))
else
# This arg is already included in the count, so no need to + 1.
(( in_alias += $#alias_args ))
# Transfer the count of this arg to the new element about to be appended.
(( in_alias[1]-- ))
fi
# Add one because we will in_alias[1]-- on the next loop iteration so
# this iteration should be considered in in_alias as well
in_alias=( $(($#alias_args + 1)) $in_alias )
(( in_redirection++ )) # Stall this arg
continue
else
Expand Down Expand Up @@ -854,7 +862,7 @@ _zsh_highlight_main_highlighter_highlight_list()
style=commandseparator
elif [[ $this_word == *':start:'* ]] && [[ $arg == $'\n' ]]; then
style=commandseparator
elif [[ $this_word == *':start:'* ]] && [[ $arg == ';' ]] && (( in_alias )); then
elif [[ $this_word == *':start:'* ]] && [[ $arg == ';' ]] && (( $#in_alias )); then
style=commandseparator
else
# Empty commands (semicolon follows nothing) are valid syntax.
Expand All @@ -879,7 +887,12 @@ _zsh_highlight_main_highlighter_highlight_list()
next_word=':start:'
highlight_glob=true
saw_assignment=false
seen_alias=()
(){
local alias_name
for alias_name in ${(k)seen_alias[(R)<$#in_alias->]}; do
unset "seen_alias[$alias_name]"
done
}
if [[ $arg != '|' && $arg != '|&' ]]; then
next_word+=':start_of_pipeline:'
fi
Expand Down Expand Up @@ -1147,7 +1160,7 @@ _zsh_highlight_main_highlighter_highlight_list()
fi
_zsh_highlight_main_add_region_highlight $start_pos $end_pos $style
done
(( in_alias == 1 )) && in_alias=0 _zsh_highlight_main_add_region_highlight $start_pos $end_pos $alias_style
(( $#in_alias )) && in_alias=() _zsh_highlight_main_add_region_highlight $start_pos $end_pos $alias_style
(( in_param == 1 )) && in_param=0 _zsh_highlight_main_add_region_highlight $start_pos $end_pos $param_style
[[ "$proc_buf" = (#b)(#s)(([[:space:]]|\\$'\n')#) ]]
REPLY=$(( end_pos + ${#match[1]} - 1 ))
Expand Down Expand Up @@ -1258,7 +1271,7 @@ _zsh_highlight_main_highlighter_check_path()

# If this word ends the buffer, check if it's the prefix of a valid path.
if (( has_end && (len == end_pos) )) &&
(( ! in_alias )) &&
(( ! $#in_alias )) &&
[[ $WIDGET != zle-line-finish ]]; then
# TODO: When we've dropped support for pre-5.0.6 zsh, use the *(Y1) glob qualifier here.
local -a tmp
Expand Down
37 changes: 37 additions & 0 deletions highlighters/main/test-data/alias-self2.zsh
Original file line number Diff line number Diff line change
@@ -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
# -------------------------------------------------------------------------------------------------

alias cat='cat | cat'

BUFFER='cat'

expected_region_highlight=(
'1 3 alias' # cat
)