Subject: Re: bug#59397: [PATCH] feature/tree-sitter: Utilize new font-lock faces for more tree-sitter backed modes

From: Randy Taylor <[email-masked]>
Date: Tue, 22 Nov 2022 22:21:20 +0000

On Monday, November 21st, 2022 at 22:38, Randy Taylor <[email-masked]> wrote:
> 
> On Monday, November 21st, 2022 at 16:49, Yuan Fu [email-masked] wrote:
> 
> > Thanks! I was busy with other things, but I’ll try to merge this soon!
> > 
> > Yuan
> 
> 
> No worries, take your time.
> 
> It's probably best to merge Theo's first (Bug#59445) since it's smaller, after which I will rebase and post a new patch.
> 

OK, latest and greatest patch attached.

From e1aa137acb9487e609004f55e41ccac8a3007dca Mon Sep 17 00:00:00 2001
From: Randy Taylor <[email-masked]>
Date: Sat, 19 Nov 2022 22:30:13 -0500
Subject: [PATCH] Utilize new font-lock faces for more tree-sitter modes
 (Bug#59397)

* lisp/progmodes/java-ts-mode.el (java-ts-mode--font-lock-settings):
Use font-lock-number-face.
(java-ts-mode): Alphabetize features.
* lisp/progmodes/js.el (js--treesit-operators): Define operators.
(js--treesit-font-lock-settings): Use bracket, delimiter,
escape-sequence, property, number, and operator font-lock faces.
(js-ts-mode): Add them to the feature list and alphabetize.
* lisp/progmodes/json-ts-mode.el (json-ts-mode--font-lock-settings):
Use bracket, delimiter, escape-sequence, and number faces.  Remove
unused features.
(json-ts-mode): Add them to the feature list and alphabetize.
* lisp/progmodes/sh-script.el (sh-mode--treesit-settings): Use
bracket, delimiter, number, misc-punctuation, and operator font-lock
faces.
(sh-mode--treesit-operators): Remove ; and ;; from list.
(bash-ts-mode): Add them to the feature list and alphabetize.
* lisp/progmodes/ts-mode.el (ts-mode--operators): Define operators.
(ts-mode--font-lock-settings): Use escape-sequence, number, and
operator font-lock faces.
(ts-mode): Add them to the feature list and alphabetize.
---
 lisp/progmodes/java-ts-mode.el | 15 +++++---
 lisp/progmodes/js.el           | 69 +++++++++++++++++++++++-----------
 lisp/progmodes/json-ts-mode.el | 32 +++++++++-------
 lisp/progmodes/sh-script.el    | 31 +++++++++++----
 lisp/progmodes/ts-mode.el      | 64 +++++++++++++++++++------------
 5 files changed, 139 insertions(+), 72 deletions(-)

diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index e78f1b4c6e8..ee2934f53c6 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -134,8 +134,7 @@ java-ts-mode--font-lock-settings
    :feature 'constant
    `(((identifier) @font-lock-constant-face
       (:match "^[A-Z_][A-Z_\\d]*$" @font-lock-constant-face))
-     (true) @font-lock-constant-face
-     (false) @font-lock-constant-face)
+     [(true) (false)] @font-lock-constant-face)
    :language 'java
    :override t
    :feature 'keyword
@@ -163,8 +162,12 @@ java-ts-mode--font-lock-settings
    :override t
    :feature 'literal
    `((null_literal) @font-lock-constant-face
-     (decimal_floating_point_literal)  @font-lock-constant-face
-     (hex_floating_point_literal) @font-lock-constant-face)
+     (binary_integer_literal)  @font-lock-number-face
+     (decimal_integer_literal) @font-lock-number-face
+     (hex_integer_literal) @font-lock-number-face
+     (octal_integer_literal) @font-lock-number-face
+     (decimal_floating_point_literal) @font-lock-number-face
+     (hex_floating_point_literal) @font-lock-number-face)
    :language 'java
    :override t
    :feature 'type
@@ -314,8 +317,8 @@ java-ts-mode
   ;; Font-lock.
   (setq-local treesit-font-lock-settings java-ts-mode--font-lock-settings)
   (setq-local treesit-font-lock-feature-list
-              '((comment keyword constant string)
-                (type definition expression literal annotation)
+              '((comment constant keyword string)
+                (annotation definition expression literal type)
                 (bracket delimiter operator)))
 
   ;; Imenu.
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 51d105b9d7d..da05b7b364a 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3465,6 +3465,13 @@ js--treesit-keywords
     "typeof" "var" "void" "while" "with" "yield")
   "JavaScript keywords for tree-sitter font-locking.")
 
+(defvar js--treesit-operators
+  '("=" "+=" "-=" "*=" "/=" "%=" "**=" "<<=" ">>=" ">>>=" "&=" "^="
+    "|=" "&&=" "||=" "??=" "==" "!=" "===" "!==" ">" ">=" "<" "<=" "+"
+    "-" "*" "/" "%" "++" "--" "**" "&" "|" "^" "~" "<<" ">>" ">>>"
+    "&&" "||" "!")
+  "JavaScript operators for tree-sitter font-locking.")
+
 (defvar js--treesit-font-lock-settings
   (treesit-font-lock-rules
 
@@ -3479,8 +3486,7 @@ js--treesit-font-lock-settings
    `(((identifier) @font-lock-constant-face
       (:match "^[A-Z_][A-Z_\\d]*$" @font-lock-constant-face))
 
-     [(true) (false) (null)] @font-lock-constant-face
-     (number) @font-lock-constant-face)
+     [(true) (false) (null)] @font-lock-constant-face)
 
    :language 'javascript
    :override t
@@ -3557,21 +3563,6 @@ js--treesit-font-lock-settings
              (member_expression
               property: (property_identifier) @font-lock-variable-name-face)]))
 
-   :language 'javascript
-   :override t
-   :feature 'property
-   `((pair key: (property_identifier) @font-lock-variable-name-face)
-
-     (pair value: (identifier) @font-lock-variable-name-face)
-
-     (pair
-      key: (property_identifier) @font-lock-function-name-face
-      value: [(function) (arrow_function)])
-
-     ((shorthand_property_identifier) @font-lock-variable-name-face)
-
-     ((shorthand_property_identifier_pattern) @font-lock-variable-name-face))
-
    :language 'javascript
    :override t
    :feature 'pattern
@@ -3596,7 +3587,42 @@ js--treesit-font-lock-settings
 
      (jsx_attribute
       (property_identifier)
-      @font-lock-constant-face)))
+      @font-lock-constant-face))
+
+   :language 'javascript
+   :feature 'number
+   `((number) @font-lock-number-face
+     ((identifier) @font-lock-number-face
+      (:match "^\\(:?NaN\\|Infinity\\)$" @font-lock-number-face)))
+
+   :language 'javascript
+   :feature 'operator
+   `([,@js--treesit-operators] @font-lock-operator-face
+     (ternary_expression ["?" ":"] @font-lock-operator-face))
+
+   :language 'javascript
+   :feature 'bracket
+   '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face)
+
+   :language 'javascript
+   :feature 'delimiter
+   '((["," "." ";" ":"]) @font-lock-delimiter-face)
+
+   :language 'javascript
+   :feature 'escape-sequence
+   :override t
+   '((escape_sequence) @font-lock-escape-face)
+
+   :language 'javascript
+   :override t
+   :feature 'property
+   `((property_identifier) @font-lock-property-face
+
+     (pair value: (identifier) @font-lock-variable-name-face)
+
+     ((shorthand_property_identifier) @font-lock-property-face)
+
+     ((shorthand_property_identifier_pattern) @font-lock-property-face)))
   "Tree-sitter font-lock settings.")
 
 (defun js--fontify-template-string (node override start end &rest _)
@@ -3846,9 +3872,10 @@ js-ts-mode
     ;; Fontification.
     (setq-local treesit-font-lock-settings js--treesit-font-lock-settings)
     (setq-local treesit-font-lock-feature-list
-                '((comment declaration)
-                  (string keyword identifier expression constant)
-                  (property pattern jsx )))
+                '(( comment declaration)
+                  ( constant expression identifier keyword number string)
+                  ( bracket delimiter escape-sequence jsx operator
+                    pattern property)))
     ;; Imenu
     (setq-local imenu-create-index-function
                 #'js--treesit-imenu)
diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el
index 4ea285bd439..101e873cf6e 100644
--- a/lisp/progmodes/json-ts-mode.el
+++ b/lisp/progmodes/json-ts-mode.el
@@ -74,26 +74,28 @@ json-ts--indent-rules
 (defvar json-ts-mode--font-lock-settings
   (treesit-font-lock-rules
    :language 'json
-   :feature 'comment
-   :override t
-   '((comment) @font-lock-comment-face)
+   :feature 'bracket
+   '((["[" "]" "{" "}"]) @font-lock-bracket-face)
    :language 'json
-   :feature 'string
-   :override t
-   '((escape_sequence) @font-lock-constant-face
-     (string) @font-lock-string-face)
+   :feature 'constant
+   '([(null) (true) (false)] @font-lock-constant-face)
+   :language 'json
+   :feature 'delimiter
+   '((["," ":"]) @font-lock-delimiter-face)
    :language 'json
    :feature 'number
-   :override t
-   '((number) @font-lock-constant-face)
+   '((number) @font-lock-number-face)
    :language 'json
-   :feature 'constant
+   :feature 'string
+   '((string) @font-lock-string-face)
+   :language 'json
+   :feature 'escape-sequence
    :override t
-   '([(null) (true) (false)] @font-lock-constant-face)
+   '((escape_sequence) @font-lock-escape-face)
    :language 'json
-   :feature 'pair
+   :feature 'error
    :override t
-   `((pair key: (_) @font-lock-variable-name-face)))
+   '((ERROR) @font-lock-warning-face))
   "Font-lock settings for JSON.")
 
 (defun json-ts-mode--imenu-1 (node)
@@ -154,7 +156,9 @@ json-ts-mode
   ;; Font-lock.
   (setq-local treesit-font-lock-settings json-ts-mode--font-lock-settings)
   (setq-local treesit-font-lock-feature-list
-              '((comment string number) (constant pair) ()))
+              '((constant number string)
+                (escape-sequence)
+                (bracket delimiter error)))
 
   ;; Imenu.
   (setq-local imenu-create-index-function #'json-ts-mode--imenu)
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 7fe31802c41..067aef86692 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -1608,9 +1608,10 @@ bash-ts-mode
   "Major mode for editing Bash shell scripts."
   (when (treesit-ready-p 'bash)
     (setq-local treesit-font-lock-feature-list
-                '((comment function string heredoc)
-                  (variable keyword command declaration-command)
-                  (constant operator builtin-variable)))
+                '(( comment function heredoc string)
+                  ( command declaration-command keyword number variable)
+                  ( bracket builtin-variable constant delimiter
+                    misc-punctuation operator)))
     (setq-local treesit-font-lock-settings
                 sh-mode--treesit-settings)
     (treesit-major-mode-setup)))
@@ -3216,8 +3217,7 @@ sh-shellcheck-flymake
 ;;; Tree-sitter font-lock
 
 (defvar sh-mode--treesit-operators
-  '("|" "|&" "||" "&&" ">" ">>" "<" "<<" "<<-" "<<<" "==" "!=" ";"
-    ";;" ";&" ";;&")
+  '("|" "|&" "||" "&&" ">" ">>" "<" "<<" "<<-" "<<<" "==" "!=" ";&" ";;&")
   "A list of `sh-mode' operators to fontify.")
 
 (defvar sh-mode--treesit-keywords
@@ -3312,7 +3312,7 @@ sh-mode--treesit-settings
 
    :feature 'operator
    :language 'bash
-   `([ ,@sh-mode--treesit-operators ] @font-lock-builtin-face)
+   `([,@sh-mode--treesit-operators] @font-lock-operator-face)
 
    :feature 'builtin-variable
    :language 'bash
@@ -3322,7 +3322,24 @@ sh-mode--treesit-settings
                   `(seq bol
                         (or ,@builtin-vars)
                         eol)))
-              @font-lock-builtin-face))))
+              @font-lock-builtin-face)))
+
+   :feature 'number
+   :language 'bash
+   `(((word) @font-lock-number-face
+      (:match "^[0-9]+$" @font-lock-number-face)))
+
+   :feature 'bracket
+   :language 'bash
+   '((["(" ")" "((" "))" "[" "]" "[[" "]]" "{" "}"]) @font-lock-bracket-face)
+
+   :feature 'delimiter
+   :language 'bash
+   '(([";" ";;"]) @font-lock-delimiter-face)
+
+   :feature 'misc-punctuation
+   :language 'bash
+   '((["$"]) @font-lock-misc-punctuation-face))
   "Tree-sitter font-lock settings for `sh-mode'.")
 
 (provide 'sh-script)
diff --git a/lisp/progmodes/ts-mode.el b/lisp/progmodes/ts-mode.el
index a91eba6501a..436b198f594 100644
--- a/lisp/progmodes/ts-mode.el
+++ b/lisp/progmodes/ts-mode.el
@@ -101,6 +101,13 @@ ts-mode--keywords
     "while" "with" "yield")
   "TypeScript keywords for tree-sitter font-locking.")
 
+(defvar ts-mode--operators
+  '("=" "+=" "-=" "*=" "/=" "%=" "**=" "<<=" ">>=" ">>>=" "&=" "^="
+    "|=" "&&=" "||=" "??=" "==" "!=" "===" "!==" ">" ">=" "<" "<=" "+"
+    "-" "*" "/" "%" "++" "--" "**" "&" "|" "^" "~" "<<" ">>" ">>>"
+    "&&" "||" "!" "?.")
+  "TypeScript operators for tree-sitter font-locking.")
+
 (defvar ts-mode--font-lock-settings
   (treesit-font-lock-rules
    :language 'tsx
@@ -114,8 +121,7 @@ ts-mode--font-lock-settings
    `(((identifier) @font-lock-constant-face
       (:match "^[A-Z_][A-Z_\\d]*$" @font-lock-constant-face))
 
-     [(true) (false) (null)] @font-lock-constant-face
-     (number) @font-lock-constant-face)
+     [(true) (false) (null)] @font-lock-constant-face)
 
    :language 'tsx
    :override t
@@ -207,25 +213,6 @@ ts-mode--font-lock-settings
        (member_expression
         property: (property_identifier) @font-lock-function-name-face)]))
 
-   :language 'tsx
-   :override t
-   :feature 'property
-   `((pair key: (property_identifier) @font-lock-property-face)
-
-     (pair value: (identifier) @font-lock-variable-name-face)
-
-     (pair
-      key: (property_identifier) @font-lock-property-face
-      value: [(function) (arrow_function)])
-
-     (property_signature
-      name: (property_identifier) @font-lock-property-face)
-
-     ((shorthand_property_identifier) @font-lock-property-face)
-
-     ((shorthand_property_identifier_pattern)
-      @font-lock-variable-name-face))
-
    :language 'tsx
    :override t
    :feature 'pattern
@@ -250,13 +237,42 @@ ts-mode--font-lock-settings
       @font-lock-function-name-face)
 
      (jsx_attribute (property_identifier) @font-lock-constant-face))
+
+   :language 'tsx
+   :feature 'number
+   `((number) @font-lock-number-face
+     ((identifier) @font-lock-number-face
+      (:match "^\\(:?NaN\\|Infinity\\)$" @font-lock-number-face)))
+
+   :language 'tsx
+   :feature 'operator
+   `([,@ts-mode--operators] @font-lock-operator-face
+     (ternary_expression ["?" ":"] @font-lock-operator-face))
+
    :language 'tsx
    :feature 'bracket
    '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face)
 
    :language 'tsx
    :feature 'delimiter
-   '((["," ":" ";"]) @font-lock-delimiter-face))
+   '((["," "." ";" ":"]) @font-lock-delimiter-face)
+
+   :language 'tsx
+   :feature 'escape-sequence
+   :override t
+   '((escape_sequence) @font-lock-escape-face)
+
+   :language 'tsx
+   :override t
+   :feature 'property
+   `(((property_identifier) @font-lock-property-face)
+
+     (pair value: (identifier) @font-lock-variable-name-face)
+
+     ((shorthand_property_identifier) @font-lock-property-face)
+
+     ((shorthand_property_identifier_pattern)
+      @font-lock-property-face)))
   "Tree-sitter font-lock settings.")
 
 ;;;###autoload
@@ -303,8 +319,8 @@ ts-mode
     (setq-local treesit-font-lock-settings ts-mode--font-lock-settings)
     (setq-local treesit-font-lock-feature-list
                 '((comment declaration)
-                  (string keyword identifier expression constant)
-                  (property pattern jsx bracket delimiter)))
+                  (constant expression identifier keyword number string)
+                  (bracket delimiter jsx pattern property)))
     ;; Imenu.
     (setq-local imenu-create-index-function #'js--treesit-imenu)
 
-- 
2.38.1