@@ -1338,8 +1338,13 @@ _zsh_highlight_main_highlighter_highlight_argument()
13381338 (( i = REPLY ))
13391339 highlights+=($reply )
13401340 continue
1341- elif [[ $arg [i+1] == $' \x28 ' && ${arg: $i } != $' \x28\x28 ' * $' \x29\x29 ' * ]]; then
1342- # command substitution that doesn't look like an arithmetic expansion
1341+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1342+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1343+ # Arithmetic expansion
1344+ (( i = REPLY ))
1345+ highlights+=($reply )
1346+ continue
1347+ fi
13431348 start=$i
13441349 (( i += 2 ))
13451350 _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
@@ -1354,10 +1359,6 @@ _zsh_highlight_main_highlighter_highlight_argument()
13541359 highlights+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter-unquoted)
13551360 fi
13561361 continue
1357- else
1358- # TODO: if it's an arithmetic expansion, skip past it, to prevent
1359- # multiplications from being highlighted as globbing (issue #607,
1360- # test-data/arith1.zsh)
13611362 fi
13621363 while [[ $arg [i+1] == [=~ # +'^'] ]]; do
13631364 (( i += 1 ))
@@ -1485,11 +1486,17 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
14851486 # $#, $*, $@, $?, $- - like $$ above
14861487 (( k += 1 )) # highlight both dollar signs
14871488 (( i += 1 )) # don't consider the second one as introducing another parameter expansion
1488- elif [[ $arg [i+1] == $' \x28 ' && ${arg: $i } != $' \x28\x28 ' * $' \x29\x29 ' * ]]; then
1489- # command substitution that doesn't look like an arithmetic expansion
1489+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1490+ saved_reply=($reply )
1491+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1492+ # Arithmetic expansion
1493+ (( i = REPLY ))
1494+ reply=($saved_reply $reply )
1495+ continue
1496+ fi
1497+
14901498 breaks+=( $last_break $(( start_pos + i - 1 )) )
14911499 (( i += 2 ))
1492- saved_reply=($reply )
14931500 _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
14941501 ret=$?
14951502 (( i += REPLY ))
@@ -1670,6 +1677,96 @@ _zsh_highlight_main_highlighter_highlight_backtick()
16701677 REPLY= $i
16711678}
16721679
1680+ # Highlight special chars inside arithmetic expansions
1681+ _zsh_highlight_main_highlighter_highlight_arithmetic ()
1682+ {
1683+ local -a saved_reply
1684+ local style
1685+ integer i j k paren_depth ret
1686+ reply=()
1687+
1688+ for (( i = $1 + 3 ; i <= end_pos - start_pos ; i += 1 )) ; do
1689+ (( j = i + start_pos - 1 ))
1690+ (( k = j + 1 ))
1691+ case " $arg [$i ]" in
1692+ [\'\"\\ @{}])
1693+ style=unknown-token
1694+ ;;
1695+ ' (' )
1696+ (( paren_depth++ ))
1697+ continue
1698+ ;;
1699+ ' )' )
1700+ if (( paren_depth )) ; then
1701+ (( paren_depth-- ))
1702+ continue
1703+ fi
1704+ [[ $arg [i+1] == ' )' ]] && { (( i++ )) ; break ; }
1705+ # Special case ) at the end of the buffer to avoid flashing command substitution for a character
1706+ (( has_end && (len == k) )) && break
1707+ # This is a single paren and there are no open parens, so this isn't an arithmetic expansion
1708+ return 1
1709+ ;;
1710+ ' `' )
1711+ saved_reply=($reply )
1712+ _zsh_highlight_main_highlighter_highlight_backtick $i
1713+ (( i = REPLY ))
1714+ reply=($saved_reply $reply )
1715+ continue
1716+ ;;
1717+ ' $' )
1718+ if [[ $arg [i+1] == $' \x28 ' ]]; then
1719+ saved_reply=($reply )
1720+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1721+ # Arithmetic expansion
1722+ (( i = REPLY ))
1723+ reply=($saved_reply $reply )
1724+ continue
1725+ fi
1726+
1727+ (( i += 2 ))
1728+ _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,end_pos]
1729+ ret=$?
1730+ (( i += REPLY ))
1731+ reply=(
1732+ $saved_reply
1733+ $j $(( start_pos + i )) command-substitution-quoted
1734+ $j $(( j + 2 )) command-substitution-delimiter-quoted
1735+ $reply
1736+ )
1737+ if (( ret == 0 )) ; then
1738+ reply+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter)
1739+ fi
1740+ continue
1741+ else
1742+ continue
1743+ fi
1744+ ;;
1745+ ($histchars [1]) # ! - may be a history expansion
1746+ if [[ $arg [i+1] != (' =' | $' \x28 ' | $' \x7b ' | [[:blank:]]) ]]; then
1747+ style=history-expansion
1748+ else
1749+ continue
1750+ fi
1751+ ;;
1752+ * )
1753+ continue
1754+ ;;
1755+
1756+ esac
1757+ reply+=($j $k $style )
1758+ done
1759+
1760+ if [[ $arg [i] != ' )' ]]; then
1761+ # If unclosed, i points past the end
1762+ (( i-- ))
1763+ fi
1764+ style=arithmetic-expansion
1765+ reply=($(( start_pos + $1 - 1 )) $(( start_pos + i )) arithmetic-expansion $reply )
1766+ REPLY=$i
1767+ }
1768+
1769+
16731770# Called with a single positional argument.
16741771# Perform filename expansion (tilde expansion) on the argument and set $REPLY to the expanded value.
16751772#
0 commit comments