@@ -1300,8 +1300,13 @@ _zsh_highlight_main_highlighter_highlight_argument()
1300
1300
(( i = REPLY ))
1301
1301
highlights+=($reply )
1302
1302
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
1305
1310
start=$i
1306
1311
(( i += 2 ))
1307
1312
_zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
@@ -1316,10 +1321,6 @@ _zsh_highlight_main_highlighter_highlight_argument()
1316
1321
highlights+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter-unquoted)
1317
1322
fi
1318
1323
continue
1319
- else
1320
- # TODO: if it's an arithmetic expansion, skip past it, to prevent
1321
- # multiplications from being highlighted as globbing (issue #607,
1322
- # test-data/arith1.zsh)
1323
1324
fi
1324
1325
while [[ $arg [i+1] == [=~ # +'^'] ]]; do
1325
1326
(( i += 1 ))
@@ -1447,11 +1448,17 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
1447
1448
# $#, $*, $@, $?, $- - like $$ above
1448
1449
(( k += 1 )) # highlight both dollar signs
1449
1450
(( 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
1451
+ elif [[ $arg [i+1] == $' \x28 ' ]]; then
1452
+ saved_reply=($reply )
1453
+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1454
+ # Arithmetic substitution
1455
+ (( i = REPLY ))
1456
+ reply=($saved_reply $reply )
1457
+ continue
1458
+ fi
1459
+
1452
1460
breaks+=( $last_break $(( start_pos + i - 1 )) )
1453
1461
(( i += 2 ))
1454
- saved_reply=($reply )
1455
1462
_zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
1456
1463
ret=$?
1457
1464
(( i += REPLY ))
@@ -1632,6 +1639,96 @@ _zsh_highlight_main_highlighter_highlight_backtick()
1632
1639
REPLY= $i
1633
1640
}
1634
1641
1642
+ # Highlight special chars inside arithmetic substitutions
1643
+ _zsh_highlight_main_highlighter_highlight_arithmetic ()
1644
+ {
1645
+ local -a saved_reply
1646
+ local style
1647
+ integer i j k paren_depth ret
1648
+ reply=()
1649
+
1650
+ for (( i = $1 + 3 ; i <= end_pos - start_pos ; i += 1 )) ; do
1651
+ (( j = i + start_pos - 1 ))
1652
+ (( k = j + 1 ))
1653
+ case " $arg [$i ]" in
1654
+ [\'\"\\ @{}])
1655
+ style=unknown-token
1656
+ ;;
1657
+ ' (' )
1658
+ (( paren_depth++ ))
1659
+ continue
1660
+ ;;
1661
+ ' )' )
1662
+ if (( paren_depth )) ; then
1663
+ (( paren_depth-- ))
1664
+ continue
1665
+ fi
1666
+ [[ $arg [i+1] == ' )' ]] && { (( i++ )) ; break ; }
1667
+ # Special case ) at the end of the buffer to avoid flashing command substitution for a character
1668
+ (( has_end && (len == k) )) && break
1669
+ # This is a single paren and there are no open parens, so this isn't an arithmetic substitution
1670
+ return 1
1671
+ ;;
1672
+ ' `' )
1673
+ saved_reply=($reply )
1674
+ _zsh_highlight_main_highlighter_highlight_backtick $i
1675
+ (( i = REPLY ))
1676
+ reply=($saved_reply $reply )
1677
+ continue
1678
+ ;;
1679
+ ' $' )
1680
+ if [[ $arg [i+1] == $' \x28 ' ]]; then
1681
+ saved_reply=($reply )
1682
+ if [[ $arg [i+2] == $' \x28 ' ]] && _zsh_highlight_main_highlighter_highlight_arithmetic $i ; then
1683
+ # Arithmetic substitution
1684
+ (( i = REPLY ))
1685
+ reply=($saved_reply $reply )
1686
+ continue
1687
+ fi
1688
+
1689
+ (( i += 2 ))
1690
+ _zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,end_pos]
1691
+ ret=$?
1692
+ (( i += REPLY ))
1693
+ reply=(
1694
+ $saved_reply
1695
+ $j $(( start_pos + i )) command-substitution-quoted
1696
+ $j $(( j + 2 )) command-substitution-delimiter-quoted
1697
+ $reply
1698
+ )
1699
+ if (( ret == 0 )) ; then
1700
+ reply+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter)
1701
+ fi
1702
+ continue
1703
+ else
1704
+ continue
1705
+ fi
1706
+ ;;
1707
+ ($histchars [1]) # ! - may be a history expansion
1708
+ if [[ $arg [i+1] != (' =' | $' \x28 ' | $' \x7b ' | [[:blank:]]) ]]; then
1709
+ style=history-expansion
1710
+ else
1711
+ continue
1712
+ fi
1713
+ ;;
1714
+ * )
1715
+ continue
1716
+ ;;
1717
+
1718
+ esac
1719
+ reply+=($j $k $style )
1720
+ done
1721
+
1722
+ if [[ $arg [i] != ' )' ]]; then
1723
+ # If unclosed, i points past the end
1724
+ (( i-- ))
1725
+ fi
1726
+ style=arithmetic-expansion
1727
+ reply=($(( start_pos + $1 - 1 )) $(( start_pos + i )) arithmetic-expansion $reply )
1728
+ REPLY=$i
1729
+ }
1730
+
1731
+
1635
1732
# Called with a single positional argument.
1636
1733
# Perform filename expansion (tilde expansion) on the argument and set $REPLY to the expanded value.
1637
1734
#
0 commit comments