]> git.eshelyaron.com Git - emacs.git/commitdiff
Add more granular features in font-locking
authorTheodor Thornhill <theo@thornhill.no>
Mon, 17 Oct 2022 10:49:19 +0000 (12:49 +0200)
committerYuan Fu <casouri@gmail.com>
Tue, 18 Oct 2022 20:42:42 +0000 (13:42 -0700)
There is now support for three font-locking levels, 'minimal',
'moderate' and 'full'.  The richest experience is to be expected from
the 'full', and all levels are enabled by default.

* lisp/progmodes/js.el (js--treesit-font-lock-settings): New defvar
renamed from 'js--treesit-settings'.

(js--treesit-font-lock-settings): New defvar renamed from
'js--json-treesit-settings'.

* lisp/progmodes/ts-mode.el (ts-mode--font-lock-settings): New defvar
renamed from 'ts-mode--settings'.

lisp/progmodes/js.el
lisp/progmodes/ts-mode.el

index 51f5b720479f7dabb7dd9943de1363fda666e16e..fa548e4df7ea245d56e197b30e69cdd025b80d7b 100644 (file)
@@ -3454,19 +3454,34 @@ indentation, which-function and movement functions."
     "debugger" "default" "delete" "do" "else" "export" "extends" "finally"
     "for" "from" "function" "get" "if" "import" "in" "instanceof" "let" "new"
     "of" "return" "set" "static" "switch" "switch" "target" "throw" "try"
-    "typeof" "var" "void" "while" "with" "yield"))
+    "typeof" "var" "void" "while" "with" "yield")
+  "JavaScript keywords for tree-sitter font-locking.")
 
-(defvar js--treesit-settings
+(defvar js--treesit-font-lock-settings
   (treesit-font-lock-rules
    :language 'javascript
-   :feature 'basic
    :override t
-   `(((identifier) @font-lock-constant-face
+   :feature 'minimal
+   `(
+     ((identifier) @font-lock-constant-face
       (:match "^[A-Z_][A-Z_\\d]*$" @font-lock-constant-face))
 
-     (new_expression
-      constructor: (identifier) @font-lock-type-face)
+     [(this) (super)] @font-lock-keyword-face
+
+     [(true) (false) (null)] @font-lock-constant-face
+     (regex pattern: (regex_pattern)) @font-lock-string-face
+     (number) @font-lock-constant-face
 
+     (string) @font-lock-string-face
+     (comment) @font-lock-comment-face
+     [,@js--treesit-keywords] @font-lock-keyword-face
+
+     (template_string) @js--fontify-template-string
+     (template_substitution ["${" "}"] @font-lock-constant-face))
+   :language 'javascript
+   :override t
+   :feature 'moderate
+   `(
      (function
       name: (identifier) @font-lock-function-name-face)
 
@@ -3479,6 +3494,21 @@ indentation, which-function and movement functions."
      (method_definition
       name: (property_identifier) @font-lock-function-name-face)
 
+     (variable_declarator
+      name: (identifier) @font-lock-variable-name-face)
+
+     (new_expression
+      constructor: (identifier) @font-lock-type-face)
+
+     (for_in_statement
+      left: (identifier) @font-lock-variable-name-face)
+
+     (arrow_function
+      parameter: (identifier) @font-lock-variable-name-face))
+   :language 'javascript
+   :override t
+   :feature 'full
+   `(
      (variable_declarator
       name: (identifier) @font-lock-function-name-face
       value: [(function) (arrow_function)])
@@ -3502,20 +3532,11 @@ indentation, which-function and movement functions."
                   property:
                   (property_identifier) @font-lock-function-name-face)])
 
-     (variable_declarator
-      name: (identifier) @font-lock-variable-name-face)
-
      (assignment_expression
       left: [(identifier) @font-lock-variable-name-face
              (member_expression
               property: (property_identifier) @font-lock-variable-name-face)])
 
-     (for_in_statement
-      left: (identifier) @font-lock-variable-name-face)
-
-     (arrow_function
-      parameter: (identifier) @font-lock-variable-name-face)
-
      (pair key: (property_identifier) @font-lock-variable-name-face)
 
      (pair value: (identifier) @font-lock-variable-name-face)
@@ -3546,20 +3567,8 @@ indentation, which-function and movement functions."
 
      (jsx_attribute
       (property_identifier)
-      @font-lock-constant-face)
-
-     [(this) (super)] @font-lock-keyword-face
-
-     [(true) (false) (null)] @font-lock-constant-face
-     (regex pattern: (regex_pattern)) @font-lock-string-face
-     (number) @font-lock-constant-face
-
-     (string) @font-lock-string-face
-     (comment) @font-lock-comment-face
-     [,@js--treesit-keywords] @font-lock-keyword-face
-
-     (template_string) @js--fontify-template-string
-     (template_substitution ["${" "}"] @font-lock-constant-face))))
+      @font-lock-constant-face)))
+  "Tree-sitter font-lock settings.")
 
 (defun js--fontify-template-string (beg end node)
   "Fontify template string but not substitution inside it.
@@ -3651,12 +3660,11 @@ For BACKEND and WARN see `treesit-mode-function'."
     (setq-local beginning-of-defun-function #'js--treesit-beginning-of-defun)
     (setq-local end-of-defun-function #'js--treesit-end-of-defun)
 
-    (setq-local font-lock-keywords-only t)
-    (setq-local treesit-font-lock-settings js--treesit-settings)
-    (setq-local treesit-font-lock-feature-list '((basic)))
-
     (add-hook 'which-func-functions #'js-treesit-current-defun nil t)
 
+    (setq-local font-lock-keywords-only t)
+  (setq-local treesit-font-lock-settings js--treesit-font-lock-settings)
+  (setq-local treesit-font-lock-feature-list '((minimal) (moderate) (full)))
     (treesit-font-lock-enable))
    ;; Elisp.
    ((eq backend 'elisp)
@@ -3753,10 +3761,10 @@ For BACKEND and WARN see `treesit-mode-function'."
   (js--backend-toggle 'elisp nil)
   (setq-local major-mode-backend-function #'js--backend-toggle))
 
-(defvar js--json-treesit-settings
+(defvar js-json--treesit-font-lock-settings
   (treesit-font-lock-rules
    :language 'json
-   :feature 'basic
+   :feature 'minimal
    :override t
    `(
      (pair
@@ -3770,8 +3778,8 @@ For BACKEND and WARN see `treesit-mode-function'."
 
      (escape_sequence) @font-lock-constant-face
 
-     (comment) @font-lock-comment-face
-     )))
+     (comment) @font-lock-comment-face))
+  "Font-lock settings for JSON.")
 
 
 (defvar js--json-treesit-indent-rules
@@ -3793,7 +3801,7 @@ For BACKEND and WARN see `treesit-mode-function'."
     (setq-local indent-line-function #'treesit-indent)
 
     (setq-local font-lock-keywords-only t)
-    (setq-local treesit-font-lock-settings js--json-treesit-settings)
+    (setq-local treesit-font-lock-settings js-json--treesit-font-lock-settings)
     (treesit-font-lock-enable))
    ;; Elisp.
    ((eq backend 'elisp)
index dffe9fcfcf292d121558c5b7b608266531398a83..a3a2d9f78e7a508b47b726afcd74fee1642dd141 100644 (file)
      (no-node parent-bol 0)))
   "Tree-sitter indent rules.")
 
-(defvar ts-mode--settings
+(defvar ts-mode--keywords
+  '("!" "abstract" "as" "async" "await" "break"
+    "case" "catch" "class" "const" "continue" "debugger"
+    "declare" "default" "delete" "do" "else" "enum"
+    "export" "extends" "finally" "for" "from" "function"
+    "get" "if" "implements" "import" "in" "instanceof" "interface"
+    "keyof" "let" "namespace" "new" "of" "private" "protected"
+    "public" "readonly" "return" "set" "static" "switch"
+    "target" "throw" "try" "type" "typeof" "var" "void"
+    "while" "with" "yield")
+  "TypeScript keywords for tree-sitter font-locking.")
+
+(defvar ts-mode--font-lock-settings
   (treesit-font-lock-rules
    :language 'tsx
    :override t
-   :feature 'basic
-   '(((identifier) @font-lock-constant-face
+   :feature 'minimal
+   `(
+     ((identifier) @font-lock-constant-face
       (:match "^[A-Z_][A-Z_\\d]*$" @font-lock-constant-face))
 
+     [,@ts-mode--keywords] @font-lock-keyword-face
+     [(this) (super)] @font-lock-keyword-face
+
+     [(true) (false) (null)] @font-lock-constant-face
+     (regex pattern: (regex_pattern)) @font-lock-string-face
+     (number) @font-lock-constant-face
+
+     (string) @font-lock-string-face
+
+     (template_string) @ts-mode--fontify-template-string
+     (template_substitution ["${" "}"] @font-lock-builtin-face)
+
+     (comment) @font-lock-comment-face)
+   :language 'tsx
+   :override t
+   :feature 'moderate
+   '(
      (nested_type_identifier
       module: (identifier) @font-lock-type-face)
+
      (type_identifier) @font-lock-type-face
+
      (predefined_type) @font-lock-type-face
 
      (new_expression
      (method_definition
       name: (property_identifier) @font-lock-function-name-face)
 
+     (variable_declarator
+      name: (identifier) @font-lock-variable-name-face)
+
+     (enum_declaration (identifier) @font-lock-type-face)
+
+     (enum_body (property_identifier) @font-lock-type-face)
+
+     (enum_assignment name: (property_identifier) @font-lock-type-face)
+
+     (assignment_expression
+      left: [(identifier) @font-lock-variable-name-face
+             (member_expression
+              property: (property_identifier) @font-lock-variable-name-face)])
+
+     (for_in_statement
+      left: (identifier) @font-lock-variable-name-face)
+
+     (arrow_function
+      parameter: (identifier) @font-lock-variable-name-face))
+   :language 'tsx
+   :override t
+   :feature 'full
+   '(
      (variable_declarator
       name: (identifier) @font-lock-function-name-face
       value: [(function) (arrow_function)])
        (member_expression
         property: (property_identifier) @font-lock-function-name-face)])
 
-     (variable_declarator
-      name: (identifier) @font-lock-variable-name-face)
-
-     (enum_declaration (identifier) @font-lock-type-face)
-
-     (enum_body (property_identifier) @font-lock-type-face)
-
-     (enum_assignment name: (property_identifier) @font-lock-type-face)
-
-     (assignment_expression
-      left: [(identifier) @font-lock-variable-name-face
-             (member_expression
-              property: (property_identifier) @font-lock-variable-name-face)])
-
-     (for_in_statement
-      left: (identifier) @font-lock-variable-name-face)
-
-     (arrow_function
-      parameter: (identifier) @font-lock-variable-name-face)
-
      (arrow_function
       parameters:
       [(_ (identifier) @font-lock-variable-name-face)
        (_ (_ (identifier) @font-lock-variable-name-face))
        (_ (_ (_ (identifier) @font-lock-variable-name-face)))])
 
-
      (pair key: (property_identifier) @font-lock-variable-name-face)
 
      (pair value: (identifier) @font-lock-variable-name-face)
       [(nested_identifier (identifier)) (identifier)]
       @font-lock-function-name-face)
 
-     (jsx_attribute (property_identifier) @font-lock-constant-face)
-
-     [(this) (super)] @font-lock-keyword-face
-
-     [(true) (false) (null)] @font-lock-constant-face
-     (regex pattern: (regex_pattern)) @font-lock-string-face
-     (number) @font-lock-constant-face
-
-     (string) @font-lock-string-face
-
-     (template_string) @js--fontify-template-string
-     (template_substitution
-      ["${" "}"] @font-lock-constant-face)
-
-     ["!"
-      "abstract"
-      "as"
-      "async"
-      "await"
-      "break"
-      "case"
-      "catch"
-      "class"
-      "const"
-      "continue"
-      "debugger"
-      "declare"
-      "default"
-      "delete"
-      "do"
-      "else"
-      "enum"
-      "export"
-      "extends"
-      "finally"
-      "for"
-      "from"
-      "function"
-      "get"
-      "if"
-      "implements"
-      "import"
-      "in"
-      "instanceof"
-      "interface"
-      "keyof"
-      "let"
-      "namespace"
-      "new"
-      "of"
-      "private"
-      "protected"
-      "public"
-      "readonly"
-      "return"
-      "set"
-      "static"
-      "switch"
-      "target"
-      "throw"
-      "try"
-      "type"
-      "typeof"
-      "var"
-      "void"
-      "while"
-      "with"
-      "yield"
-      ] @font-lock-keyword-face
-
-     (comment) @font-lock-comment-face
-     ))
+     (jsx_attribute (property_identifier) @font-lock-constant-face)))
   "Tree-sitter font-lock settings.")
 
+(defun ts-mode--fontify-template-string (beg end node)
+  "Fontify template string but not substitution inside it.
+BEG, END, NODE refers to the template_string node."
+  (ignore end)
+  ;; Stolen from `js--fontify-template-string'
+  (let ((child (treesit-node-child node 0)))
+    (while child
+      (if (equal (treesit-node-type child) "template_substitution")
+          (put-text-property beg (treesit-node-start child)
+                             'face 'font-lock-string-face)
+        (put-text-property beg (treesit-node-end child)
+                           'face 'font-lock-string-face))
+      (setq beg (treesit-node-end child)
+            child (treesit-node-next-sibling child)))))
+
 (defvar ts-mode--defun-type-regexp
   (rx (or "class_declaration"
           "method_definition"
@@ -351,9 +329,8 @@ ARG is the same as in `end-of-defun."
     (setq-local end-of-defun-function #'ts-mode--end-of-defun)
 
     (setq font-lock-keywords-only t)
-    (setq-local treesit-font-lock-settings ts-mode--settings)
-
-    (setq treesit-font-lock-feature-list '((basic)))
+    (setq-local treesit-font-lock-settings ts-mode--font-lock-settings)
+    (setq treesit-font-lock-feature-list '((minimal) (moderate) (full)))
     (treesit-font-lock-enable))
    (t
     (message "Tree-sitter for TypeScript isn't available, falling back to `js-mode'")