Skip to content

Commit 8066185

Browse files
committed
main: Highlight partially quoted arguments correctly
Closes zsh-users#130
1 parent 461684b commit 8066185

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

highlighters/main/main-highlighter.zsh

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -671,19 +671,7 @@ _zsh_highlight_highlighter_main_paint()
671671
;|
672672
'--'*) style=double-hyphen-option;;
673673
'-'*) style=single-hyphen-option;;
674-
"'"*) _zsh_highlight_main_highlighter_highlight_single_quote 1
675-
already_added=1
676-
;;
677-
'"'*) _zsh_highlight_main_highlighter_highlight_double_quote
678-
already_added=1
679-
;;
680-
\$\'*) _zsh_highlight_main_highlighter_highlight_dollar_quote
681-
already_added=1
682-
;;
683674
'`'*) style=back-quoted-argument;;
684-
[$][*]) style=default;;
685-
[*?]*|*[^\\][*?]*)
686-
$highlight_glob && style=globbing || style=default;;
687675
*) if false; then
688676
elif [[ $arg = $'\x7d' ]] && $right_brace_is_recognised_everywhere; then
689677
# was handled by the $'\x7d' case above
@@ -701,7 +689,8 @@ _zsh_highlight_highlighter_main_paint()
701689
if _zsh_highlight_main_highlighter_check_path; then
702690
style=$REPLY
703691
else
704-
style=default
692+
_zsh_highlight_main_highlighter_highlight_argument
693+
already_added=1
705694
fi
706695
fi
707696
;;
@@ -800,6 +789,41 @@ _zsh_highlight_main_highlighter_check_path()
800789
return 1
801790
}
802791

792+
# Highlight an argument and possibly special chars in quotes
793+
_zsh_highlight_main_highlighter_highlight_argument()
794+
{
795+
local i
796+
797+
_zsh_highlight_main_add_region_highlight $start_pos $end_pos default
798+
for (( i = 1 ; i <= end_pos - start_pos ; i += 1 )); do
799+
case "$arg[$i]" in
800+
"\\") (( i += 1 )); continue;;
801+
"'") _zsh_highlight_main_highlighter_highlight_single_quote $i; (( i = REPLY ));;
802+
'"') _zsh_highlight_main_highlighter_highlight_double_quote $i; (( i = REPLY ));;
803+
'$')
804+
if [[ $arg[i+1] == "'" ]]; then
805+
_zsh_highlight_main_highlighter_highlight_dollar_quote $i
806+
(( i = REPLY ))
807+
elif [[ $arg[i+1] == [\^=~#+] ]]; then
808+
while [[ $arg[i+1] == [\^=~#+] ]]; do
809+
(( i += 1 ))
810+
done
811+
if [[ $arg[i+1] == [*@#?-$!] ]]; then
812+
(( i += 1 ))
813+
fi
814+
elif [[ $arg[i+1] == [*@#?-$!] ]]; then
815+
(( i += 1 ))
816+
fi;;
817+
[*?])
818+
if $highlight_glob; then
819+
_zsh_highlight_main_add_region_highlight $start_pos $end_pos globbing
820+
break
821+
fi;;
822+
*) continue;;
823+
esac
824+
done
825+
}
826+
803827
# Highlight single-quoted strings
804828
_zsh_highlight_main_highlighter_highlight_single_quote()
805829
{
@@ -826,11 +850,11 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
826850
local MATCH; integer MBEGIN MEND
827851
local i j k style
828852

829-
# Starting quote is at 1, so start parsing at offset 2 in the string.
830-
for (( i = 2 ; i < end_pos - start_pos ; i += 1 )) ; do
853+
for (( i = $1 + 1 ; i < end_pos - start_pos ; i += 1 )) ; do
831854
(( j = i + start_pos - 1 ))
832855
(( k = j + 1 ))
833856
case "$arg[$i]" in
857+
'"') break;;
834858
'$' ) style=dollar-double-quoted-argument
835859
# Look for an alphanumeric parameter name.
836860
if [[ ${arg:$i} =~ ^([A-Za-z_][A-Za-z0-9_]*|[0-9]+) ]] ; then
@@ -874,8 +898,9 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
874898
highlights+=($j $k $style)
875899
done
876900

877-
highlights=($start_pos $end_pos double-quoted-argument $highlights)
901+
highlights=($(( start_pos + $1 - 1)) $(( start_pos + i )) double-quoted-argument $highlights)
878902
_zsh_highlight_main_add_region_highlights $highlights
903+
REPLY=$i
879904
}
880905

881906
# Highlight special chars inside dollar-quoted strings
@@ -887,11 +912,11 @@ _zsh_highlight_main_highlighter_highlight_dollar_quote()
887912
local AA
888913
integer c
889914

890-
# Starting dollar-quote is at 1:2, so start parsing at offset 3 in the string.
891-
for (( i = 3 ; i < end_pos - start_pos ; i += 1 )) ; do
915+
for (( i = $1 + 2 ; i < end_pos - start_pos ; i += 1 )) ; do
892916
(( j = i + start_pos - 1 ))
893917
(( k = j + 1 ))
894918
case "$arg[$i]" in
919+
"'") break;;
895920
"\\") style=back-dollar-quoted-argument
896921
for (( c = i + 1 ; c <= end_pos - start_pos ; c += 1 )); do
897922
[[ "$arg[$c]" != ([0-9xXuUa-fA-F]) ]] && break
@@ -920,8 +945,9 @@ _zsh_highlight_main_highlighter_highlight_dollar_quote()
920945
highlights+=($j $k $style)
921946
done
922947

923-
highlights+=($start_pos $end_pos dollar-quoted-argument $highlights)
948+
highlights+=($(( start_pos + $1 - 1 )) $(( start_pos + i )) dollar-quoted-argument $highlights)
924949
_zsh_highlight_main_add_region_highlights $highlights
950+
REPLY=$i
925951
}
926952

927953
# Called with a single positional argument.

0 commit comments

Comments
 (0)