Subject: Re: bug#59268: [PATCH] Utilize new font-lock faces for C/C++ and Python tree-sitter use

From: Randy Taylor <[email-masked]>
Date: Thu, 17 Nov 2022 13:50:27 +0000

On Wednesday, November 16th, 2022 at 22:39, Yuan Fu <[email-masked]> wrote:

> 
> Ah, for making you updating the patch for so many times! I just see this report. The only comment I have is that I see you removed the field rule from assignment feature:
> 

No worries!

>
> - (assignment_expression
> - left: (field_expression field: (_) @font-lock-property-face))
> 
> I envisioned the assignment feature to highlight “the thing being assigned to”, in which case it would highlight the field when it’s in LHS. It’s perfectly fine to have both the field rule and the assignment rule to highlight fields, I think. So if you don’t mind, I’d add it back to assignment group.
> 

I removed it because (field_identifier) @font-lock-property-face (in the property feature) highlights all fields, from what I can tell and have tested.
Can you show me an example where it won't match?

Below, when T is a struct:

  T thing;
  thing.b = thing.b;
  thing.b = 5;

b is highlighted as a field in all cases.

Also, I've attached an updated patch: it seems that the escape-sequence feature needs an override to work (probably because it's inside a string that's highlighted?).

From bb93e32e7e921becc2b76184acfd3a4a99fde4ff Mon Sep 17 00:00:00 2001
From: Randy Taylor <[email-masked]>
Date: Sun, 13 Nov 2022 22:06:33 -0500
Subject: [PATCH] Utilize new font-lock faces for C/C++ and Python tree-sitter
 use

* lisp/progmodes/c-ts-mode.el (c-ts-mode--font-lock-settings): Use new
escape, number, property, operator, bracket, and delimiter font-lock
faces.
(c-ts-mode--base-mode): Add them to the feature list.
(c-ts-mode): Fix typo.
* lisp/progmodes/python.el (python--treesit-settings): Use new number,
property, operator, bracket, and delimiter font-lock faces.
(python-mode): Add them to the feature list.
---
 lisp/progmodes/c-ts-mode.el | 46 +++++++++++++++++++++++--------------
 lisp/progmodes/python.el    | 41 ++++++++++++++++++++++++++++-----
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index b951031d81..8816660f89 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -230,19 +230,17 @@ c-ts-mode--font-lock-settings
 
    :language mode
    :feature 'operator
-   :override t
    `([,@c-ts-mode--operators] @font-lock-operator-face
      "!" @font-lock-negation-char-face)
 
    :language mode
    :feature 'string
    `((string_literal) @font-lock-string-face
-     (system_lib_string) @font-lock-string-face
-     (escape_sequence) @font-lock-escape-face)
+     (system_lib_string) @font-lock-string-face)
 
    :language mode
    :feature 'literal
-   `((number_literal) @font-lock-constant-face
+   `((number_literal) @font-lock-number-face
      (char_literal) @font-lock-constant-face)
 
    :language mode
@@ -268,14 +266,11 @@ c-ts-mode--font-lock-settings
       declarator: (_) @c-ts-mode--fontify-struct-declarator)
 
      (function_definition
-      declarator: (_) @c-ts-mode--fontify-struct-declarator)
+      declarator: (_) @c-ts-mode--fontify-struct-declarator))
 
      ;; Should we highlight identifiers in the parameter list?
      ;; (parameter_declaration
-     ;;  declarator: (_) @c-ts-mode--fontify-struct-declarator)
-
-     (enumerator
-      name: (identifier) @font-lock-variable-name-face))
+     ;;  declarator: (_) @c-ts-mode--fontify-struct-declarator))
 
    :language mode
    :feature 'assignment
@@ -284,8 +279,6 @@ c-ts-mode--font-lock-settings
    ;; inspiration.
    '((assignment_expression
       left: (identifier) @font-lock-variable-name-face)
-     (assignment_expression
-      left: (field_expression field: (_) @font-lock-property-face))
      (assignment_expression
       left: (pointer_expression
              (identifier) @font-lock-variable-name-face))
@@ -298,8 +291,7 @@ c-ts-mode--font-lock-settings
    '((call_expression
       function: (identifier) @font-lock-function-name-face)
      (field_expression
-      argument: (identifier) @font-lock-variable-name-face
-      field: (field_identifier) @font-lock-property-face)
+      argument: (identifier) @font-lock-variable-name-face)
      (pointer_expression
       (identifier) @font-lock-variable-name-face))
 
@@ -313,6 +305,25 @@ c-ts-mode--font-lock-settings
    :feature 'error
    '((ERROR) @font-lock-warning-face)
 
+   :feature 'escape-sequence
+   :language mode
+   :override t
+   '((escape_sequence) @font-lock-escape-face)
+
+   :language mode
+   :feature 'property
+   '((field_identifier) @font-lock-property-face
+     (enumerator
+      name: (identifier) @font-lock-property-face))
+
+   :language mode
+   :feature 'bracket
+   '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face)
+
+   :language mode
+   :feature 'delimiter
+   '((["," ":" ";"]) @font-lock-delimiter-face)
+
    :language mode
    :feature 'emacs-devel
    '(((call_expression function: (identifier) @fn)
@@ -471,9 +482,10 @@ c-ts-mode--base-mode
   (setq-local which-func-functions nil)
 
   (setq-local treesit-font-lock-feature-list
-              '((comment preprocessor constant string literal keyword)
-                (type definition label assignment)
-                (expression error operator))))
+              '(( comment constant keyword literal preprocessor string)
+                ( assignment definition label property type)
+                ( bracket delimiter error escape-sequence expression
+                  operator))))
 
 ;;;###autoload
 (define-derived-mode c-ts-mode c-ts-mode--base-mode "C"
@@ -500,7 +512,7 @@ c-ts-mode
 
 ;;;###autoload
 (define-derived-mode c++-ts-mode c-ts-mode--base-mode "C++"
-  "Major mode for editing C, powered by tree-sitter."
+  "Major mode for editing C++, powered by tree-sitter."
   :group 'c++
 
   (unless (treesit-ready-p nil 'cpp)
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index ad4665eb19..22485a025e 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -975,11 +975,8 @@ python--treesit-constants
     "copyright" "credits" "exit" "license" "quit"))
 
 (defvar python--treesit-operators
-  ;; This is not used. And and, or, not, is, in are fontified as
-  ;; keywords.
   '("-" "-=" "!=" "*" "**" "**=" "*=" "/" "//" "//=" "/=" "&" "%" "%="
-    "^" "+" "+=" "<" "<<" "<=" "<>" "=" "==" ">" ">=" ">>" "|" "~"
-    "and" "in" "is" "not" "or"))
+    "^" "+" "+=" "<" "<<" "<=" "<>" "=" "==" ">" ">=" ">>" "|" "~"))
 
 (defvar python--treesit-special-attributes
   '("__annotations__" "__closure__" "__code__"
@@ -1117,7 +1114,38 @@ python--treesit-settings
    :feature 'escape-sequence
    :language 'python
    :override t
-   '((escape_sequence) @font-lock-escape-face))
+   '((escape_sequence) @font-lock-escape-face)
+
+   :feature 'number
+   :language 'python
+   :override t
+   '([(integer) (float)] @font-lock-number-face)
+
+   :feature 'property
+   :language 'python
+   :override t
+   '((attribute
+      attribute: (identifier) @font-lock-property-face)
+     (class_definition
+      body: (block
+             (expression_statement
+              (assignment left:
+                          (identifier) @font-lock-property-face)))))
+
+   :feature 'operator
+   :language 'python
+   :override t
+   `([,@python--treesit-operators] @font-lock-operator-face)
+
+   :feature 'bracket
+   :language 'python
+   :override t
+   '(["(" ")" "[" "]" "{" "}"] @font-lock-bracket-face)
+
+   :feature 'delimiter
+   :language 'python
+   :override t
+   '(["," "." ":" ";" (ellipsis)] @font-lock-delimiter-face))
   "Tree-sitter font-lock settings.")
 
 
@@ -6553,7 +6581,8 @@ python-mode
                 '(( comment string function-name class-name)
                   ( keyword builtin constant type)
                   ( assignment decorator escape-sequence
-                    string-interpolation)))
+                    string-interpolation number property
+                    operator bracket delimiter)))
     (setq-local treesit-font-lock-settings python--treesit-settings)
     (setq-local imenu-create-index-function
                 #'python-imenu-treesit-create-index)
-- 
2.38.1