@@ -1300,8 +1300,13 @@ _zsh_highlight_main_highlighter_highlight_argument()
13001300 (( i = REPLY ))
13011301 highlights+=($reply )
13021302 continue
1303- elif [[ $arg [i+1] == $' \x28 ' && ${arg: $i } != $' \x28\x28 ' * $' \x29\x29 ' * ]]; then
1304- # command substitution that doesn't look like an arithmetic expansion
1303+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1304+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1305+ # Arithmetic substitution
1306+ (( i = REPLY ))
1307+ highlights+=($reply )
1308+ continue
1309+ fi
13051310 start=$i
13061311 (( i += 2 ))
13071312 _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
@@ -1447,11 +1452,17 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
14471452 # $#, $*, $@, $?, $- - like $$ above
14481453 (( k += 1 )) # highlight both dollar signs
14491454 (( i += 1 )) # don't consider the second one as introducing another parameter expansion
1450- elif [[ $arg [i+1] == $' \x28 ' && ${arg: $i } != $' \x28\x28 ' * $' \x29\x29 ' * ]]; then
1451- # command substitution that doesn't look like an arithmetic expansion
1455+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1456+ saved_reply=($reply )
1457+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1458+ # Arithmetic substitution
1459+ (( i = REPLY ))
1460+ reply=($saved_reply $reply )
1461+ continue
1462+ fi
1463+
14521464 breaks+=( $last_break $(( start_pos + i - 1 )) )
14531465 (( i += 2 ))
1454- saved_reply=($reply )
14551466 _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
14561467 ret=$?
14571468 (( i += REPLY ))
@@ -1632,6 +1643,100 @@ _zsh_highlight_main_highlighter_highlight_backtick()
16321643 REPLY= $i
16331644}
16341645
1646+ # Highlight special chars inside arithmetic substitutions
1647+ _zsh_highlight_main_highlighter_highlight_arithmetic ()
1648+ {
1649+ local -a match mbegin mend saved_reply
1650+ local MATCH; integer MBEGIN MEND
1651+ local i j k ret style
1652+ integer paren_depth
1653+ reply=()
1654+
1655+ for (( i = $1 + 3 ; i <= end_pos - start_pos ; i += 1 )) ; do
1656+ (( j = i + start_pos - 1 ))
1657+ (( k = j + 1 ))
1658+ case " $arg [$i ]" in
1659+ ' )' )
1660+ if (( paren_depth )) ; then
1661+ (( paren_depth-- ))
1662+ continue
1663+ fi
1664+ [[ $arg [i+1] == ' )' ]] && break
1665+ # Special case ) at the end of the buffer to avoid flashing command substitution for a character
1666+ (( has_end && (len == k) )) && break
1667+ # This is a single paren and there are no open parens, so this isn't an arithmetic substitution
1668+ return 1
1669+ ;;
1670+ ' (' )
1671+ (( paren_depth++ ))
1672+ continue
1673+ ;;
1674+ [\'\"\\ ])
1675+ style=unknown-token
1676+ ;;
1677+ ' `' )
1678+ saved_reply=($reply )
1679+ _zsh_highlight_main_highlighter_highlight_backtick $i
1680+ (( i = REPLY ))
1681+ reply=($saved_reply $reply )
1682+ continue
1683+ ;;
1684+ ' $' )
1685+ if [[ $arg [i+1] == $' \x28 ' ]]; then
1686+ saved_reply=($reply )
1687+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1688+ # Arithmetic substitution
1689+ (( i = REPLY ))
1690+ reply=($saved_reply $reply )
1691+ continue
1692+ fi
1693+
1694+ (( i += 2 ))
1695+ _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,end_pos]
1696+ ret=$?
1697+ (( i += REPLY ))
1698+ reply=(
1699+ $saved_reply
1700+ $j $(( start_pos + i )) command-substitution-quoted
1701+ $j $(( j + 2 )) command-substitution-delimiter-quoted
1702+ $reply
1703+ )
1704+ if (( ret == 0 )) ; then
1705+ reply+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter)
1706+ fi
1707+ continue
1708+ else
1709+ continue
1710+ fi
1711+ ;;
1712+ ($histchars [1]) # ! - may be a history expansion
1713+ if [[ $arg [i+1] != (' =' | $' \x28 ' | $' \x7b ' | [[:blank:]]) ]]; then
1714+ style=history-expansion
1715+ else
1716+ continue
1717+ fi
1718+ ;;
1719+ * )
1720+ continue
1721+ ;;
1722+
1723+ esac
1724+ reply+=($j $k $style )
1725+ done
1726+
1727+ if [[ $arg [i,i+1] == ' ))' ]]; then
1728+ style=arithmetic-expansion
1729+ (( i++ ))
1730+ else
1731+ # If unclosed, i points past the end
1732+ (( i-- ))
1733+ style=arithmetic-expansion-unclosed
1734+ fi
1735+ reply=($(( start_pos + $1 - 1 )) $(( start_pos + i )) $style $reply )
1736+ REPLY=$i
1737+ }
1738+
1739+
16351740# Called with a single positional argument.
16361741# Perform filename expansion (tilde expansion) on the argument and set $REPLY to the expanded value.
16371742#
0 commit comments