@@ -1350,8 +1350,13 @@ _zsh_highlight_main_highlighter_highlight_argument()
13501350 (( i = REPLY ))
13511351 highlights+=($reply )
13521352 continue
1353- elif [[ $arg [i+1] == $' \x28 ' && ${arg: $i } != $' \x28\x28 ' * $' \x29\x29 ' * ]]; then
1354- # command substitution that doesn't look like an arithmetic expansion
1353+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1354+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1355+ # Arithmetic expansion
1356+ (( i = REPLY ))
1357+ highlights+=($reply )
1358+ continue
1359+ fi
13551360 start=$i
13561361 (( i += 2 ))
13571362 _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
@@ -1366,10 +1371,6 @@ _zsh_highlight_main_highlighter_highlight_argument()
13661371 highlights+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter-unquoted)
13671372 fi
13681373 continue
1369- else
1370- # TODO: if it's an arithmetic expansion, skip past it, to prevent
1371- # multiplications from being highlighted as globbing (issue #607,
1372- # test-data/arith1.zsh)
13731374 fi
13741375 while [[ $arg [i+1] == [=~ # +'^'] ]]; do
13751376 (( i += 1 ))
@@ -1497,11 +1498,17 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
14971498 # $#, $*, $@, $?, $- - like $$ above
14981499 (( k += 1 )) # highlight both dollar signs
14991500 (( i += 1 )) # don't consider the second one as introducing another parameter expansion
1500- elif [[ $arg [i+1] == $' \x28 ' && ${arg: $i } != $' \x28\x28 ' * $' \x29\x29 ' * ]]; then
1501- # command substitution that doesn't look like an arithmetic expansion
1501+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1502+ saved_reply=($reply )
1503+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1504+ # Arithmetic expansion
1505+ (( i = REPLY ))
1506+ reply=($saved_reply $reply )
1507+ continue
1508+ fi
1509+
15021510 breaks+=( $last_break $(( start_pos + i - 1 )) )
15031511 (( i += 2 ))
1504- saved_reply=($reply )
15051512 _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
15061513 ret=$?
15071514 (( i += REPLY ))
@@ -1682,6 +1689,96 @@ _zsh_highlight_main_highlighter_highlight_backtick()
16821689 REPLY= $i
16831690}
16841691
1692+ # Highlight special chars inside arithmetic expansions
1693+ _zsh_highlight_main_highlighter_highlight_arithmetic ()
1694+ {
1695+ local -a saved_reply
1696+ local style
1697+ integer i j k paren_depth ret
1698+ reply=()
1699+
1700+ for (( i = $1 + 3 ; i <= end_pos - start_pos ; i += 1 )) ; do
1701+ (( j = i + start_pos - 1 ))
1702+ (( k = j + 1 ))
1703+ case " $arg [$i ]" in
1704+ [\'\"\\ @{}])
1705+ style=unknown-token
1706+ ;;
1707+ ' (' )
1708+ (( paren_depth++ ))
1709+ continue
1710+ ;;
1711+ ' )' )
1712+ if (( paren_depth )) ; then
1713+ (( paren_depth-- ))
1714+ continue
1715+ fi
1716+ [[ $arg [i+1] == ' )' ]] && { (( i++ )) ; break ; }
1717+ # Special case ) at the end of the buffer to avoid flashing command substitution for a character
1718+ (( has_end && (len == k) )) && break
1719+ # This is a single paren and there are no open parens, so this isn't an arithmetic expansion
1720+ return 1
1721+ ;;
1722+ ' `' )
1723+ saved_reply=($reply )
1724+ _zsh_highlight_main_highlighter_highlight_backtick $i
1725+ (( i = REPLY ))
1726+ reply=($saved_reply $reply )
1727+ continue
1728+ ;;
1729+ ' $' )
1730+ if [[ $arg [i+1] == $' \x28 ' ]]; then
1731+ saved_reply=($reply )
1732+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1733+ # Arithmetic expansion
1734+ (( i = REPLY ))
1735+ reply=($saved_reply $reply )
1736+ continue
1737+ fi
1738+
1739+ (( i += 2 ))
1740+ _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,end_pos]
1741+ ret=$?
1742+ (( i += REPLY ))
1743+ reply=(
1744+ $saved_reply
1745+ $j $(( start_pos + i )) command-substitution-quoted
1746+ $j $(( j + 2 )) command-substitution-delimiter-quoted
1747+ $reply
1748+ )
1749+ if (( ret == 0 )) ; then
1750+ reply+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter)
1751+ fi
1752+ continue
1753+ else
1754+ continue
1755+ fi
1756+ ;;
1757+ ($histchars [1]) # ! - may be a history expansion
1758+ if [[ $arg [i+1] != (' =' | $' \x28 ' | $' \x7b ' | [[:blank:]]) ]]; then
1759+ style=history-expansion
1760+ else
1761+ continue
1762+ fi
1763+ ;;
1764+ * )
1765+ continue
1766+ ;;
1767+
1768+ esac
1769+ reply+=($j $k $style )
1770+ done
1771+
1772+ if [[ $arg [i] != ' )' ]]; then
1773+ # If unclosed, i points past the end
1774+ (( i-- ))
1775+ fi
1776+ style=arithmetic-expansion
1777+ reply=($(( start_pos + $1 - 1 )) $(( start_pos + i )) arithmetic-expansion $reply )
1778+ REPLY=$i
1779+ }
1780+
1781+
16851782# Called with a single positional argument.
16861783# Perform filename expansion (tilde expansion) on the argument and set $REPLY to the expanded value.
16871784#
0 commit comments