Skip to content

Commit 747d36f

Browse files
committed
main: Run the entirety of aliases through the state machine
Fixes zsh-users#544 zsh-users#552 zsh-users#554 zsh-users#555
1 parent af951c4 commit 747d36f

13 files changed

+67
-66
lines changed

highlighters/main/main-highlighter.zsh

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ _zsh_highlight_main_add_region_highlight() {
7272
integer start=$1 end=$2
7373
shift 2
7474

75+
(( in_alias > 0 )) && return
76+
(( in_alias < 0 )) && in_alias=$(( 0 - in_alias ))
77+
7578
# The calculation was relative to $buf but region_highlight is relative to $BUFFER.
7679
(( start += buf_offset ))
7780
(( end += buf_offset ))
@@ -363,10 +366,13 @@ _zsh_highlight_highlighter_main_paint()
363366
_zsh_highlight_main_highlighter_highlight_list()
364367
{
365368
integer start_pos end_pos=0 buf_offset=$1 has_end=$3
366-
local buf=$4 highlight_glob=true arg arg_raw style
369+
local arg buf=$4 highlight_glob=true last_alias style
367370
local in_array_assignment=false # true between 'a=(' and the matching ')'
368-
integer len=$#buf
371+
# in_alias is set to -<number of (z)-args from expanding the alias>
372+
# After processing the first arg, invert and decrement, so no additional styles are applied.
373+
integer in_alias=0 len=$#buf
369374
local -a match mbegin mend list_highlights
375+
local -A seen_alias
370376
list_highlights=()
371377

372378
# "R" for round
@@ -429,8 +435,9 @@ _zsh_highlight_main_highlighter_highlight_list()
429435
while (( $#args )); do
430436
# Save an unmunged copy of the current word.
431437
arg=$args[1]
432-
arg_raw="$arg"
433438
shift args
439+
(( in_alias > 0 )) && (( in_alias-- ))
440+
(( in_alias == 0 )) && seen_alias=() && last_alias=
434441

435442
# Initialize this_word and next_word.
436443
if (( in_redirection == 0 )); then
@@ -455,7 +462,7 @@ _zsh_highlight_main_highlighter_highlight_list()
455462
fi
456463
fi
457464

458-
if true; then
465+
if (( in_alias == 0 )); then
459466
# Compute the new $start_pos and $end_pos, skipping over whitespace in $buf.
460467
start_pos=$end_pos
461468
if [[ $arg == ';' ]] ; then
@@ -531,62 +538,45 @@ _zsh_highlight_main_highlighter_highlight_list()
531538
# Expand aliases.
532539
_zsh_highlight_main__type "$arg"
533540
local res="$REPLY"
534-
if [[ $res == "alias" ]]; then
535-
() {
536-
local -A seen_arg
537-
while [[ $REPLY == alias ]]; do
538-
seen_arg[$arg]=1
539-
_zsh_highlight_main__resolve_alias $arg
540-
# Use a temporary array to ensure the subscript is interpreted as
541-
# an array subscript, not as a scalar subscript
542-
local -a reply
543-
# TODO: the ${interactive_comments+set} path needs to skip comments; see test-data/alias-comment1.zsh
544-
reply=( ${interactive_comments-${(z)REPLY}}
545-
${interactive_comments+${(zZ+c+)REPLY}} )
546-
# Avoid looping forever on alias a=b b=c c=b, but allow alias foo='foo bar'
547-
[[ $arg == $reply[1] ]] && break
548-
arg=$reply[1]
549-
if (( $+seen_arg[$arg] )); then
550-
res=none
551-
break
552-
fi
553-
_zsh_highlight_main__type "$arg"
554-
done
555-
}
556-
_zsh_highlight_main_highlighter_expand_path $arg
557-
arg=$REPLY
558-
() {
559-
# Make sure to use $arg_raw here, rather than $arg.
560-
integer insane_alias
561-
case $arg_raw in
562-
# Issue #263: aliases with '=' on their LHS.
563-
#
564-
# There are three cases:
565-
#
566-
# - Unsupported, breaks 'alias -L' output, but invokable:
567-
('='*) :;;
568-
# - Unsupported, not invokable:
569-
(*'='*) insane_alias=1;;
570-
# - The common case:
571-
(*) :;;
572-
esac
573-
if (( insane_alias )); then
574-
style=unknown-token
575-
# Calling 'type' again; since __type memoizes the answer, this call is just a hash lookup.
576-
elif ! _zsh_highlight_main__type "$arg" || [[ $REPLY == 'none' ]]; then
577-
style=unknown-token
578-
else
579-
# The common case.
580-
style=alias
581-
if (( ${+precommand_options[(re)"$arg"]} )) && (( ! ${+precommand_options[(re)"$arg_raw"]} )); then
582-
precommand_options[$arg_raw]=$precommand_options[$arg]
583-
fi
584-
fi
585-
}
541+
if [[ $res == "alias" ]] && [[ $last_alias != $arg ]]; then
542+
if (( $+seen_alias[$arg] )); then
543+
_zsh_highlight_main_add_region_highlight $start_pos $end_pos unknown-token
544+
continue
545+
fi
546+
_zsh_highlight_main__resolve_alias $arg
547+
# Use a temporary array to ensure the subscript is interpreted as
548+
# an array subscript, not as a scalar subscript
549+
local -a alias_args
550+
# TODO: the ${interactive_comments+set} path needs to skip comments; see test-data/alias-comment1.zsh
551+
alias_args=( ${interactive_comments-${(z)REPLY}}
552+
${interactive_comments+${(zZ+c+)REPLY}} )
553+
case $arg in
554+
# Issue #263: aliases with '=' on their LHS.
555+
#
556+
# There are three cases:
557+
#
558+
# - Unsupported, breaks 'alias -L' output, but invokable:
559+
('='*) :;;
560+
# - Unsupported, not invokable:
561+
(*'='*)
562+
_zsh_highlight_main_add_region_highlight $start_pos $end_pos unknown-token
563+
continue
564+
;;
565+
# - The common case:
566+
(*) :;;
567+
esac
568+
# Avoid looping forever on alias a=b b=c c=b, but allow alias foo='foo bar'
569+
seen_alias[$arg]=1
570+
last_alias=$arg
571+
args=( $alias_args $args )
572+
(( in_alias == 0 )) && _zsh_highlight_main_add_region_highlight $start_pos $end_pos alias
573+
in_alias=-$#alias_args
574+
(( in_redirection++ )) # Stall this arg
575+
continue
586576
else
587577
_zsh_highlight_main_highlighter_expand_path $arg
588578
arg=$REPLY
589-
_zsh_highlight_main__type "$arg"
579+
_zsh_highlight_main__type "$arg" 0
590580
res="$REPLY"
591581
fi
592582
fi
@@ -635,7 +625,7 @@ _zsh_highlight_main_highlighter_highlight_list()
635625
arg=${(P)MATCH}
636626
;;
637627
esac
638-
_zsh_highlight_main__type "$arg"
628+
_zsh_highlight_main__type "$arg" 0
639629
res=$REPLY
640630
fi
641631
}

highlighters/main/test-data/alias-comment1.zsh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ alias x=$'# foo\npwd'
3333
BUFFER='x'
3434

3535
expected_region_highlight=(
36-
"1 1 alias 'interactivecomments applies to aliases'" # x becomes pwd
36+
'1 1 alias' # x
37+
'1 1 comment' # x (#)
3738
)

highlighters/main/test-data/alias-comment2.zsh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ alias x=$'# foo\npwd'
3333
BUFFER='x'
3434

3535
expected_region_highlight=(
36-
"1 1 unknown-token" # x becomes #
36+
'1 1 alias' # x
37+
'1 1 unknown-token' # x (#)
3738
)

highlighters/main/test-data/alias-loop.zsh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ alias a=b b=c c=b
3333
BUFFER='a foo; :'
3434

3535
expected_region_highlight=(
36-
'1 1 unknown-token' # a
36+
'1 1 alias' # a
37+
'1 1 unknown-token' # a (invalid alias loop)
3738
'3 5 default' # foo
3839
'6 6 commandseparator' # ;
3940
'8 8 builtin' # :

highlighters/main/test-data/alias-nested-precommand.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ BUFFER='a -u phy1729 echo; :'
3535

3636
expected_region_highlight=(
3737
'1 1 alias' # a
38+
'1 1 precommand' # a (sudo)
3839
'3 4 single-hyphen-option' # -u
3940
'6 12 default' # phy1729
4041
'14 17 builtin' # echo

highlighters/main/test-data/alias-nested.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ BUFFER='a foo; :'
3434

3535
expected_region_highlight=(
3636
'1 1 alias' # a
37+
'1 1 builtin' # a (:)
3738
'3 5 default' # foo
3839
'6 6 commandseparator' # ;
3940
'8 8 builtin' # :

highlighters/main/test-data/alias-precommand-option-argument.zsh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ BUFFER='sdu phy1729 echo foo'
3535

3636
expected_region_highlight=(
3737
'1 3 alias' # sdu
38-
'5 11 default "issue #540"' # phy1729
38+
'1 3 precommand' # sdu (sudo)
39+
'5 11 default' # phy1729
3940
'13 16 commmand "issue #540"' # echo (not builtin)
4041
'18 20 default' # foo
4142
)

highlighters/main/test-data/alias-quoted.zsh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ expected_region_highlight=(
3535
'1 3 unknown-token' # "a"
3636
'5 7 default' # foo
3737
'8 8 commandseparator' # ;
38-
'10 12 command "issue #544' # \ls
38+
'10 12 command' # \ls
3939
)

highlighters/main/test-data/alias-redirect.zsh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ alias x=\>
3131
BUFFER='x foo echo bar'
3232

3333
expected_region_highlight=(
34-
'1 1 redirection' # x becomes >
34+
'1 1 alias' # x
35+
'1 1 redirection' # x (>)
3536
'3 5 default' # foo
3637
'7 10 builtin' # echo
3738
'12 14 default' # bar

highlighters/main/test-data/alias-self.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ BUFFER='echo bar'
3434

3535
expected_region_highlight=(
3636
'1 4 alias' # echo
37+
'1 4 builtin' # echo
3738
'6 8 default' # bar
3839
)

highlighters/main/test-data/alias.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ fi
5151
expected_region_highlight+=(
5252
"9 9 commandseparator" # ;
5353
"11 16 alias" # alias1
54+
"11 16 function" # alias1 (unused which is a function by alias1() {})
5455
)

highlighters/main/test-data/noglob-alias.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ BUFFER='x ls'
3232

3333
expected_region_highlight=(
3434
"1 1 alias" # x
35+
"1 1 precommand" # x (command)
3536
"3 4 command" # ls
3637
)

highlighters/main/test-data/off-by-one.zsh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ f() {}
3333
BUFFER='a;f;'
3434

3535
expected_region_highlight=(
36-
"1 1 alias" # f
36+
"1 1 alias" # a
37+
"1 1 builtin" # a (:)
3738
"2 2 commandseparator" # ;
38-
"3 3 function" # g
39+
"3 3 function" # f
3940
"4 4 commandseparator" # ;
4041
)

0 commit comments

Comments
 (0)