@@ -1015,7 +1015,7 @@ lines."
1015
1015
(progn
1016
1016
(forward-comment most-positive-fixnum)
1017
1017
(memq (char-after ) '(?\, ?\; ?\] ?\) ?\} ))))
1018
- do (forward-sexp )))
1018
+ do (forward-sexp )))
1019
1019
while (and (eq (char-after ) ?\n )
1020
1020
(save-excursion
1021
1021
(forward-char )
@@ -1686,6 +1686,82 @@ point of view of font-lock. It applies highlighting directly with
1686
1686
; ; Matcher always "fails"
1687
1687
nil )
1688
1688
1689
+ (defun typescript--function-argument-matcher (limit )
1690
+ " Font-lock matcher for variables in argument lists.
1691
+
1692
+ Because the syntax of the argument list is shared between
1693
+ functions, arrow functions and methods, this same matcher is used
1694
+ for all of them. The context for the search is set up as
1695
+ anchored matcher.
1696
+
1697
+ This is a cc-mode-style matcher that *always* fails, from the
1698
+ point of view of font-lock. It applies highlighting directly
1699
+ with `font-lock-apply-highlight' ."
1700
+ (condition-case nil
1701
+ (save-restriction
1702
+ (widen )
1703
+ (narrow-to-region (point-min ) limit)
1704
+ (while (re-search-forward
1705
+ (rx (group
1706
+ (regexp " [a-zA-Z_$]\\ (?:\\ s_\\ |\\ sw\\ )*" )
1707
+ ; ; name can be optionally followed by ? to mark
1708
+ ; ; the argument optional
1709
+ (? " ?" ))
1710
+ (* whitespace)
1711
+ (group (or " ," " :" " )"
1712
+ ; ; last variable in the list with a
1713
+ ; ; paren on next line and no hanging
1714
+ ; ; comma. extra logic is added to deal
1715
+ ; ; with possible comments after the
1716
+ ; ; variable.
1717
+ eol
1718
+ (and (* whitespace) (or " //" " /*" ) (* any) eol))))
1719
+ nil t )
1720
+ (font-lock-apply-highlight '(1 font-lock-variable-name-face t ))
1721
+
1722
+ ; ; If ender is a ":" it means that the currently matched
1723
+ ; ; variable also has a type signature.
1724
+ (let ((ender (match-string 2 )))
1725
+ ; ; We need to skip the type specification. The regexp
1726
+ ; ; basically either searches for the next thing which we
1727
+ ; ; believe is a parameter or the end of the argument list.
1728
+ (when (equal ender " :" )
1729
+ (let ((perform-match t ))
1730
+ (while (and perform-match
1731
+ (re-search-forward
1732
+ (rx (or
1733
+ ; ; variable without type at the end
1734
+ ; ; of line
1735
+ (and " ," eol)
1736
+ ; ; next thing is a functional
1737
+ ; ; argument, such as f:(x) => void
1738
+ (and " (" )
1739
+ ; ; closing of a function type argument.
1740
+ ; ; here, the type of `f' .
1741
+ ; ; (f: (x: number) => foo): void => { }
1742
+ (and " )" (? (* whitespace) " =>" (* whitespace)))
1743
+ (and " ,"
1744
+ (* whitespace)
1745
+ (regexp " [a-zA-Z_$]\\ (?:\\ s_\\ |\\ sw\\ )*" )
1746
+ ; ; optional ? to mark the
1747
+ ; ; argument optional
1748
+ (? " ?" )
1749
+ (group (or " :" " )" )))))
1750
+ nil t ))
1751
+ ; ; In case the skipped type was the end of a
1752
+ ; ; function type argument, the next token is the
1753
+ ; ; return type of the inner function, so we need to
1754
+ ; ; match but not fontify the next "name" (which
1755
+ ; ; really is the type).
1756
+ (if (string-match-p " =>" (match-string 0 ))
1757
+ (setq perform-match t )
1758
+ (goto-char (match-beginning 0 ))
1759
+ (setq perform-match nil ))))))))
1760
+ ; ; conditions to handle
1761
+ (scan-error nil )
1762
+ (end-of-buffer nil ))
1763
+ nil )
1764
+
1689
1765
(defun typescript--in-documentation-comment-p ()
1690
1766
" Reports whether point is inside a documentation comment."
1691
1767
(let ((parse (syntax-ppss )))
@@ -1855,16 +1931,48 @@ and searches for the next token to be highlighted."
1855
1931
(concat " \\ _<instanceof\\ _>\\ s-+\\ (" typescript--dotted-name-re " \\ )" )
1856
1932
(list 1 'font-lock-type-face ))
1857
1933
1858
- ; ; formal parameters
1934
+ ; ; formal parameters in "function" function call
1935
+ ; ; function helloWorld(a: number, b: Promise<number>): void { }
1859
1936
,(list
1860
1937
(concat
1861
1938
" \\ _<function\\ _>\\ (\\ s-+" typescript--name-re " \\ )?\\ s-*\\ (<.*>\\ )?\\ s-*(\\ s-*"
1862
1939
" \\ (?:$\\ |" typescript--name-start-re " \\ )" )
1863
- `(,( concat " \\ ( " typescript--name-re " \\ ) \\ (?: \\ s-*? \\ ([,:)] \\ |$ \\ ) \\ ) " )
1864
- (prog1 (save-excursion (re-search-forward " ) " nil t ))
1940
+ `(typescript--function-argument-matcher
1941
+ (prog1 (save-excursion (ignore-errors ( up-list )) ( point ))
1865
1942
(backward-char ))
1866
1943
nil
1867
- (1 font-lock-variable-name-face ))))
1944
+ nil ))
1945
+
1946
+ ; ; formal parameters in arrow function
1947
+ ; ; const helloWorld = (a: number, b: Promise<number>): void => { }
1948
+ ,(list
1949
+ (rx (group " =>" ) (* whitespace) (? eol) (* whitespace) " {" )
1950
+ '(1 font-lock-keyword-face )
1951
+ `(typescript--function-argument-matcher
1952
+ (prog1 (progn
1953
+ (backward-char )
1954
+ (typescript--backward-to-parameter-list)
1955
+ (point ))
1956
+ (backward-sexp ))
1957
+ (re-search-forward " {" nil t )
1958
+ nil ))
1959
+
1960
+ ; ; formal parameters in method definitions
1961
+ ; ; class Foo { helloWorld(a: number, b: Promise<number>): void { } }
1962
+ ,(list
1963
+ typescript--function-call-re
1964
+ `(typescript--function-argument-matcher
1965
+ (let ((point-orig (point ))
1966
+ (is-method-def
1967
+ (ignore-errors
1968
+ (up-list )
1969
+ (looking-at-p
1970
+ (rx (* (or whitespace ?\n )) (or " :" " {" ))))))
1971
+ (if is-method-def
1972
+ (prog1 (point ) (goto-char point-orig))
1973
+ (point )))
1974
+ nil
1975
+ nil )))
1868
1976
" Level three font lock for `typescript-mode' ." )
1869
1977
1870
1978
(defun typescript--flyspell-mode-predicate ()
0 commit comments