@@ -1338,8 +1338,13 @@ _zsh_highlight_main_highlighter_highlight_argument()
1338
1338
(( i = REPLY ))
1339
1339
highlights+=($reply )
1340
1340
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
1343
1348
start=$i
1344
1349
(( i += 2 ))
1345
1350
_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()
1354
1359
highlights+=($(( start_pos + i - 1 )) $(( start_pos + i )) command-substitution-delimiter-unquoted)
1355
1360
fi
1356
1361
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)
1361
1362
fi
1362
1363
while [[ $arg [i+1] == [=~ # +'^'] ]]; do
1363
1364
(( i += 1 ))
@@ -1485,11 +1486,17 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
1485
1486
# $#, $*, $@, $?, $- - like $$ above
1486
1487
(( k += 1 )) # highlight both dollar signs
1487
1488
(( 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
+
1490
1498
breaks+=( $last_break $(( start_pos + i - 1 )) )
1491
1499
(( i += 2 ))
1492
- saved_reply=($reply )
1493
1500
_zsh_highlight_main_highlighter_highlight_list $(( start_pos + i - 1 )) S $has_end $arg [i,-1]
1494
1501
ret=$?
1495
1502
(( i += REPLY ))
@@ -1670,6 +1677,96 @@ _zsh_highlight_main_highlighter_highlight_backtick()
1670
1677
REPLY= $i
1671
1678
}
1672
1679
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
+
1673
1770
# Called with a single positional argument.
1674
1771
# Perform filename expansion (tilde expansion) on the argument and set $REPLY to the expanded value.
1675
1772
#
0 commit comments