From 2c19f6087efe466894e1fe47121515d32d6a6d1c Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Fri, 28 Nov 2025 00:10:17 -0800 Subject: [PATCH] Remove the cached values in tree-sitter modes (bug#79363) The cached values are not needed anymore since Emacs now caches the compiled queries. * lisp/progmodes/cmake-ts-mode.el: (cmake-ts-mode--indent-rules-cached): Remove. (cmake-ts-mode--indent-rules): Return values directly. (cmake-ts-mode--font-lock-settings-cached): Remove. (cmake-ts-mode--font-lock-settings): Return values directly. * lisp/progmodes/php-ts-mode.el: (php-ts-mode--font-lock-settings-cached): Remove. (php-ts-mode--font-lock-settings): Return values directly. (php-ts-mode--custom-html-font-lock-settings-cached): Remove. (php-ts-mode--custom-html-font-lock-settings): Return values directly. * lisp/textmodes/mhtml-ts-mode.el: (mhtml-ts-mode--treesit-font-lock-settings-cached): Remove. (mhtml-ts-mode--treesit-font-lock-settings): Return values directly. (mhtml-ts-mode--treesit-indent-rules-cached): Remove. (mhtml-ts-mode--treesit-indent-rules): Return values directly. * lisp/progmodes/cmake-ts-mode.el: (cmake-ts-mode--indent-rules-cached): Remove (cmake-ts-mode--indent-rules): Return values directly. (cmake-ts-mode--font-lock-settings-cached): Remove. (cmake-ts-mode--font-lock-settings): Return values directly. * lisp/progmodes/csharp-mode.el: (csharp-ts-mode--font-lock-settings-cached): Remove. (csharp-ts-mode--font-lock-settings): Return values directly. --- lisp/progmodes/cmake-ts-mode.el | 156 ++++---- lisp/progmodes/csharp-mode.el | 660 ++++++++++++++++---------------- lisp/progmodes/js.el | 362 +++++++++--------- lisp/progmodes/php-ts-mode.el | 406 ++++++++++---------- lisp/textmodes/mhtml-ts-mode.el | 80 ++-- 5 files changed, 796 insertions(+), 868 deletions(-) diff --git a/lisp/progmodes/cmake-ts-mode.el b/lisp/progmodes/cmake-ts-mode.el index 60d03f50a12..8930f96a2cf 100644 --- a/lisp/progmodes/cmake-ts-mode.el +++ b/lisp/progmodes/cmake-ts-mode.el @@ -61,35 +61,27 @@ table) "Syntax table for `cmake-ts-mode'.") -(defvar cmake-ts-mode--indent-rules-cached nil - "Cached tree-sitter indent rules for `cmake-ts-mode'.") - (defun cmake-ts-mode--indent-rules () - "Return tree-sitter indent rules for `cmake-ts-mode'. - -Tree-sitter indent rules are evaluated the first time this function is -called. Subsequent calls return the first evaluated value." - (or cmake-ts-mode--indent-rules-cached - (setq cmake-ts-mode--indent-rules-cached - `((cmake - ((node-is ")") parent-bol 0) - ((node-is "else_command") parent-bol 0) - ((node-is "elseif_command") parent-bol 0) - ((node-is "endforeach_command") parent-bol 0) - ((node-is "endfunction_command") parent-bol 0) - ((node-is "endif_command") parent-bol 0) - ((parent-is "foreach_loop") parent-bol cmake-ts-mode-indent-offset) - ((parent-is "function_def") parent-bol cmake-ts-mode-indent-offset) - ((parent-is "if_condition") parent-bol cmake-ts-mode-indent-offset) - ((parent-is "normal_command") parent-bol cmake-ts-mode-indent-offset) - ;; Release v0.4.0 wraps arguments in an argument_list node. - ,@(ignore-errors - (treesit-query-capture 'cmake '((argument_list) @capture)) - `(((parent-is "argument_list") grand-parent cmake-ts-mode-indent-offset))) - ;; Release v0.3.0 wraps the body of commands into a body node. - ,@(ignore-errors - (treesit-query-capture 'cmake '((body) @capture)) - `(((parent-is "body") grand-parent cmake-ts-mode-indent-offset)))))))) + "Return tree-sitter indent rules for `cmake-ts-mode'." + `((cmake + ((node-is ")") parent-bol 0) + ((node-is "else_command") parent-bol 0) + ((node-is "elseif_command") parent-bol 0) + ((node-is "endforeach_command") parent-bol 0) + ((node-is "endfunction_command") parent-bol 0) + ((node-is "endif_command") parent-bol 0) + ((parent-is "foreach_loop") parent-bol cmake-ts-mode-indent-offset) + ((parent-is "function_def") parent-bol cmake-ts-mode-indent-offset) + ((parent-is "if_condition") parent-bol cmake-ts-mode-indent-offset) + ((parent-is "normal_command") parent-bol cmake-ts-mode-indent-offset) + ;; Release v0.4.0 wraps arguments in an argument_list node. + ,@(ignore-errors + (treesit-query-capture 'cmake '((argument_list) @capture)) + `(((parent-is "argument_list") grand-parent cmake-ts-mode-indent-offset))) + ;; Release v0.3.0 wraps the body of commands into a body node. + ,@(ignore-errors + (treesit-query-capture 'cmake '((body) @capture)) + `(((parent-is "body") grand-parent cmake-ts-mode-indent-offset)))))) (defvar cmake-ts-mode--constants '("ON" "TRUE" "YES" "Y" "OFF" "FALSE" "NO" "N" "IGNORE" "NOTFOUND") @@ -148,76 +140,68 @@ Check if a node type is available, then return the right font lock rules." eol)) @font-lock-constant-face)))))))) -(defvar cmake-ts-mode--font-lock-settings-cached nil - "Cached tree-sitter font-lock settings for `cmake-ts-mode'.") - (defun cmake-ts-mode--font-lock-settings () - "Return tree-sitter font-lock settings for `cmake-ts-mode'. + "Return tree-sitter font-lock settings for `cmake-ts-mode'." + (treesit-font-lock-rules + :language 'cmake + :feature 'bracket + '((["(" ")"]) @font-lock-bracket-face) -Tree-sitter font-lock settings are evaluated the first time this -function is called. Subsequent calls return the first evaluated value." - (or cmake-ts-mode--font-lock-settings-cached - (setq cmake-ts-mode--font-lock-settings-cached - (treesit-font-lock-rules - :language 'cmake - :feature 'bracket - '((["(" ")"]) @font-lock-bracket-face) + :language 'cmake + :feature 'builtin + (cmake-ts-mode--font-lock-compatibility-fe9b5e0) - :language 'cmake - :feature 'builtin - (cmake-ts-mode--font-lock-compatibility-fe9b5e0) + :language 'cmake + :feature 'comment + '([(bracket_comment) (line_comment)] @font-lock-comment-face) - :language 'cmake - :feature 'comment - '([(bracket_comment) (line_comment)] @font-lock-comment-face) + :language 'cmake + :feature 'constant + `(((argument) @font-lock-constant-face + (:match ,(rx-to-string + `(seq bol + (or ,@cmake-ts-mode--constants) + eol)) + @font-lock-constant-face))) - :language 'cmake - :feature 'constant - `(((argument) @font-lock-constant-face - (:match ,(rx-to-string - `(seq bol - (or ,@cmake-ts-mode--constants) - eol)) - @font-lock-constant-face))) + :language 'cmake + :feature 'function + '((normal_command (identifier) @font-lock-function-call-face)) - :language 'cmake - :feature 'function - '((normal_command (identifier) @font-lock-function-call-face)) + :language 'cmake + :feature 'keyword + `([,@cmake-ts-mode--keywords] @font-lock-keyword-face) - :language 'cmake - :feature 'keyword - `([,@cmake-ts-mode--keywords] @font-lock-keyword-face) + :language 'cmake + :feature 'number + '(((unquoted_argument) @font-lock-number-face + (:match "\\`-?[[:digit:]]*\\.?[[:digit:]]*\\.?[[:digit:]]+\\'" + @font-lock-number-face))) - :language 'cmake - :feature 'number - '(((unquoted_argument) @font-lock-number-face - (:match "\\`-?[[:digit:]]*\\.?[[:digit:]]*\\.?[[:digit:]]+\\'" - @font-lock-number-face))) + :language 'cmake + :feature 'string + '([(bracket_argument) (quoted_argument)] @font-lock-string-face) - :language 'cmake - :feature 'string - '([(bracket_argument) (quoted_argument)] @font-lock-string-face) + :language 'cmake + :feature 'escape-sequence + :override t + '((escape_sequence) @font-lock-escape-face) - :language 'cmake - :feature 'escape-sequence - :override t - '((escape_sequence) @font-lock-escape-face) + :language 'cmake + :feature 'misc-punctuation + ;; Don't override strings. + :override 'nil + '((["$" "{" "}"]) @font-lock-misc-punctuation-face) - :language 'cmake - :feature 'misc-punctuation - ;; Don't override strings. - :override 'nil - '((["$" "{" "}"]) @font-lock-misc-punctuation-face) + :language 'cmake + :feature 'variable + :override t + '((variable) @font-lock-variable-use-face) - :language 'cmake - :feature 'variable - :override t - '((variable) @font-lock-variable-use-face) - - :language 'cmake - :feature 'error - :override t - '((ERROR) @font-lock-warning-face))))) + :language 'cmake + :feature 'error + :override t + '((ERROR) @font-lock-warning-face))) (defun cmake-ts-mode--defun-name (node) "Return the defun name of NODE. diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index 5656b5d00ba..1a31e3f9ab9 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -779,345 +779,337 @@ compilation and evaluation time conflicts." (if (csharp-ts-mode--test-method-declaration-type-field) 'type: 'returns:)) -(defvar csharp-ts-mode--font-lock-settings-cached nil - "Cached tree-sitter font-lock settings for `csharp-ts-mode'.") - (defun csharp-ts-mode--font-lock-settings () - "Return tree-sitter font-lock settings for `csharp-ts-mode'. + "Return tree-sitter font-lock settings for `csharp-ts-mode'." + (treesit-font-lock-rules + :language 'c-sharp + :feature 'expression + '((conditional_expression (identifier) @font-lock-variable-use-face) + (postfix_unary_expression (identifier)* @font-lock-variable-use-face) + (initializer_expression (assignment_expression left: (identifier) @font-lock-property-use-face)) + (anonymous_object_creation_expression + (identifier) @font-lock-property-use-face + (identifier) @font-lock-variable-use-face) + (anonymous_object_creation_expression + (identifier) @font-lock-property-use-face + [(object_creation_expression) + (integer_literal) + (string_literal) + (binary_expression) + (invocation_expression) + (member_access_expression) + (conditional_expression)]) + (interpolated_string_expression + (interpolation + (identifier) @font-lock-variable-use-face)) + (interpolated_string_expression + (interpolation + (member_access_expression + name: (identifier) @font-lock-property-use-face))) + ((interpolated_string_expression + (interpolation + (member_access_expression + expression: (identifier) @font-lock-variable-use-face))) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((element_access_expression (identifier) @font-lock-variable-use-face) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((element_access_expression (identifier) @font-lock-variable-use-face) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((return_statement (identifier) @font-lock-variable-use-face) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((return_statement (member_access_expression + expression: (identifier) @font-lock-variable-use-face)) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((is_pattern_expression + expression: (identifier) @font-lock-variable-use-face) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((is_pattern_expression + expression: (member_access_expression + expression: (identifier) @font-lock-variable-use-face)) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + (is_pattern_expression + expression: (member_access_expression + name: (identifier) @font-lock-property-use-face)) + (is_pattern_expression + pattern: (constant_pattern (identifier) @font-lock-type-face)) + (is_pattern_expression + pattern: (constant_pattern (member_access_expression + name: (identifier) @font-lock-type-face))) + ((binary_expression + left: (identifier) @font-lock-variable-use-face) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + ((binary_expression + right: (identifier) @font-lock-variable-use-face) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + (assignment_expression + right: (identifier) @font-lock-variable-use-face) + (expression_statement ;; capture parent node to NOT shadow variable_declaration. + (assignment_expression + left: (identifier) @font-lock-variable-use-face)) + (if_statement condition: (identifier) @font-lock-variable-use-face) -Tree-sitter font-lock settings are evaluated the first time this -function is called. Subsequent calls return the first evaluated value." - (or csharp-ts-mode--font-lock-settings-cached - (setq csharp-ts-mode--font-lock-settings-cached - (treesit-font-lock-rules - :language 'c-sharp - :feature 'expression - '((conditional_expression (identifier) @font-lock-variable-use-face) - (postfix_unary_expression (identifier)* @font-lock-variable-use-face) - (initializer_expression (assignment_expression left: (identifier) @font-lock-property-use-face)) - (anonymous_object_creation_expression - (identifier) @font-lock-property-use-face - (identifier) @font-lock-variable-use-face) - (anonymous_object_creation_expression - (identifier) @font-lock-property-use-face - [(object_creation_expression) - (integer_literal) - (string_literal) - (binary_expression) - (invocation_expression) - (member_access_expression) - (conditional_expression)]) - (interpolated_string_expression - (interpolation - (identifier) @font-lock-variable-use-face)) - (interpolated_string_expression - (interpolation - (member_access_expression - name: (identifier) @font-lock-property-use-face))) - ((interpolated_string_expression - (interpolation - (member_access_expression - expression: (identifier) @font-lock-variable-use-face))) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((element_access_expression (identifier) @font-lock-variable-use-face) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((element_access_expression (identifier) @font-lock-variable-use-face) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((return_statement (identifier) @font-lock-variable-use-face) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((return_statement (member_access_expression - expression: (identifier) @font-lock-variable-use-face)) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((is_pattern_expression - expression: (identifier) @font-lock-variable-use-face) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((is_pattern_expression - expression: (member_access_expression - expression: (identifier) @font-lock-variable-use-face)) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - (is_pattern_expression - expression: (member_access_expression - name: (identifier) @font-lock-property-use-face)) - (is_pattern_expression - pattern: (constant_pattern (identifier) @font-lock-type-face)) - (is_pattern_expression - pattern: (constant_pattern (member_access_expression - name: (identifier) @font-lock-type-face))) - ((binary_expression - left: (identifier) @font-lock-variable-use-face) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - ((binary_expression - right: (identifier) @font-lock-variable-use-face) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - (assignment_expression - right: (identifier) @font-lock-variable-use-face) - (expression_statement ;; capture parent node to NOT shadow variable_declaration. - (assignment_expression - left: (identifier) @font-lock-variable-use-face)) - (if_statement condition: (identifier) @font-lock-variable-use-face) + ;; handle more specific matchers before generalized variable-use fallback. + (invocation_expression + function: (member_access_expression + name: (identifier) @font-lock-function-call-face)) + (invocation_expression + function: (member_access_expression + name: (generic_name (identifier) @font-lock-function-call-face))) + (member_access_expression + expression: (identifier) @font-lock-variable-use-face + name: (identifier) @font-lock-property-use-face)) - ;; handle more specific matchers before generalized variable-use fallback. - (invocation_expression - function: (member_access_expression - name: (identifier) @font-lock-function-call-face)) - (invocation_expression - function: (member_access_expression - name: (generic_name (identifier) @font-lock-function-call-face))) - (member_access_expression - expression: (identifier) @font-lock-variable-use-face + :language 'c-sharp + :feature 'bracket + '((["(" ")" "[" "]" "{" "}" (interpolation_brace)]) @font-lock-bracket-face) + + :language 'c-sharp + :feature 'delimiter + '((["," ":" ";"]) @font-lock-delimiter-face) + + :language 'c-sharp + :feature 'error + '((ERROR) @font-lock-warning-face) + + :language 'c-sharp + :override t + :feature 'comment + '((comment) @font-lock-comment-face) + + :language 'c-sharp + :override t + :feature 'keyword + `([,@csharp-ts-mode--keywords] @font-lock-keyword-face + (modifier) @font-lock-keyword-face + ,@(if (csharp-ts-mode--test-this-expression) + '((this_expression) @font-lock-keyword-face) + '("this" @font-lock-keyword-face)) + + ;; avoid fontifying indentifiers with a keyword-values as identifiers. + ((identifier) @font-lock-keyword-face + (:match ,(concat "\\`" (regexp-opt csharp-ts-mode--keywords t) "\\'") @font-lock-keyword-face))) + + :language 'c-sharp + :override t + :feature 'attribute + `((attribute_list + "[" @csharp-ts-mode-attribute-face + (attribute name: (identifier) @csharp-ts-mode-attribute-face) + "]" @csharp-ts-mode-attribute-face)) + + :language 'c-sharp + :override t + :feature 'escape-sequence + '((escape_sequence) @font-lock-escape-face) + + :language 'c-sharp + :override t + :feature 'literal + `((integer_literal) @font-lock-number-face + (real_literal) @font-lock-number-face + (null_literal) @font-lock-constant-face + (boolean_literal) @font-lock-constant-face) + + :language 'c-sharp + :feature 'string + `([(string_literal) + (verbatim_string_literal) + ,@ (when (csharp-ts-mode--test-string-content) + '((string_content) + "\"")) + ,@(if (csharp-ts-mode--test-interpolated-string-text) + '((interpolated_string_text) + (interpolated_verbatim_string_text) + (character_literal) + "\"" + "$\"" + "@$\"" + "$@\"") + '((interpolation_start) + (interpolation_quote)))] + @font-lock-string-face) + + :language 'c-sharp + :feature 'type + `((predefined_type) @font-lock-type-face + (implicit_type) @font-lock-type-face + (nullable_type) @font-lock-type-face + (type_parameter + (identifier) @font-lock-type-face) + (type_argument_list + (identifier) @font-lock-type-face) + (type_argument_list + (generic_name + (identifier) @font-lock-type-face)) + (base_list + (generic_name + (identifier) @font-lock-type-face)) + (array_type + (identifier) @font-lock-type-face) + (qualified_name + name: (generic_name (identifier) @font-lock-type-face)) + (cast_expression (identifier) @font-lock-type-face) + (cast_expression (generic_name (identifier) @font-lock-type-face)) + ["operator"] @font-lock-type-face + (type_parameter_constraints_clause + (identifier) @font-lock-type-face) + ,@(if (csharp-ts-mode--test-type-constraint) + '((type_constraint type: (identifier) @font-lock-type-face) + (type_constraint type: (generic_name (identifier) @font-lock-type-face))) + '((type_parameter_constraint (type type: (identifier) @font-lock-type-face)) + (type_parameter_constraint (type type: (generic_name (identifier) @font-lock-type-face))))) + + ,@(when (csharp-ts-mode--test-type-of-expression) + '((type_of_expression (identifier) @font-lock-type-face))) + + ,@(when (csharp-ts-mode--test-typeof-expression) + '((typeof_expression (identifier) @font-lock-type-face))) + + (object_creation_expression + type: (identifier) @font-lock-type-face) + (object_creation_expression + type: (generic_name (identifier) @font-lock-type-face)) + (as_expression right: (identifier) @font-lock-type-face) + (as_expression right: (generic_name (identifier) @font-lock-type-face))) + + :language 'c-sharp + :feature 'definition + `((qualified_name (identifier) @font-lock-type-face) + (using_directive (identifier) @font-lock-type-face) + ,@(when (csharp-ts-mode--test-name-equals) + '((using_directive (name_equals + (identifier) @font-lock-type-face)))) + + (enum_declaration (identifier) @font-lock-type-face) + (enum_member_declaration (identifier) @font-lock-variable-name-face) + (field_declaration (variable_declaration (variable_declarator + name: (identifier) @font-lock-variable-name-face))) + + (interface_declaration (identifier) @font-lock-type-face) + + (struct_declaration (identifier) @font-lock-type-face) + + (record_declaration (identifier) @font-lock-type-face) + (namespace_declaration (identifier) @font-lock-type-face) + (base_list (identifier) @font-lock-type-face) + (property_declaration + type: (nullable_type) @font-lock-type-face + name: (identifier) @font-lock-variable-name-face) + (property_declaration + type: (predefined_type) @font-lock-type-face + name: (identifier) @font-lock-variable-name-face) + (property_declaration + type: (identifier) @font-lock-type-face + name: (identifier) @font-lock-variable-name-face) + (class_declaration (identifier) @font-lock-type-face) + + (constructor_declaration name: (_) @font-lock-type-face) + ;; Handle different releases of tree-sitter-c-sharp. + ;; Check if keyword void_keyword is available, then return the correct rule." + ,@(condition-case nil + (progn (treesit-query-capture 'csharp '((void_keyword) @capture)) + `((method_declaration ,csharp-ts-mode--type-field [(identifier) (void_keyword)] @font-lock-type-face))) + (error + `((method_declaration ,csharp-ts-mode--type-field [(identifier) (predefined_type)] @font-lock-type-face)))) + (method_declaration ,csharp-ts-mode--type-field (generic_name (identifier) @font-lock-type-face)) + (method_declaration name: (_) @font-lock-function-name-face) + + ;; only fontify known expression-types, to avoid the need to use :override + ;; for lambda-expressions in 'function below. + (variable_declarator + name: (identifier) @font-lock-variable-name-face + [(object_creation_expression) + (integer_literal) + (string_literal) + (binary_expression) + (invocation_expression) + (await_expression) + (member_access_expression) + (conditional_expression)]) + + (catch_declaration + ((identifier) @font-lock-type-face)) + (catch_declaration + ((identifier) @font-lock-type-face + (identifier) @font-lock-variable-name-face)) + + (variable_declaration (identifier) @font-lock-type-face) + (variable_declaration (qualified_name + name: (generic_name (identifier) @font-lock-type-face))) + (variable_declaration (generic_name (identifier) @font-lock-type-face)) + + (parameter type: (identifier) @font-lock-type-face) + (parameter type: (generic_name (identifier) @font-lock-type-face)) + (parameter name: (identifier) @font-lock-variable-name-face) + + (lambda_expression (identifier) @font-lock-variable-name-face) + (lambda_expression + parameters: (implicit_parameter) @font-lock-variable-name-face) + + (declaration_expression type: (identifier) @font-lock-type-face) + (declaration_expression name: (identifier) @font-lock-variable-name-face)) + + :language 'c-sharp + :feature 'function + '((invocation_expression + function: (identifier) @font-lock-function-call-face) + ((invocation_expression + function: (member_access_expression + expression: (identifier) @font-lock-variable-use-face)) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + (argument (identifier) @font-lock-variable-use-face) + ((argument (member_access_expression + expression: (identifier) @font-lock-variable-use-face)) + (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) + (argument (member_access_expression name: (identifier) @font-lock-property-use-face)) + ;; only highlight as function if variable contains lambda expression + (variable_declarator + name: (identifier) @font-lock-function-name-face + (lambda_expression))) - :language 'c-sharp - :feature 'bracket - '((["(" ")" "[" "]" "{" "}" (interpolation_brace)]) @font-lock-bracket-face) - - :language 'c-sharp - :feature 'delimiter - '((["," ":" ";"]) @font-lock-delimiter-face) - - :language 'c-sharp - :feature 'error - '((ERROR) @font-lock-warning-face) - - :language 'c-sharp - :override t - :feature 'comment - '((comment) @font-lock-comment-face) - - :language 'c-sharp - :override t - :feature 'keyword - `([,@csharp-ts-mode--keywords] @font-lock-keyword-face - (modifier) @font-lock-keyword-face - ,@(if (csharp-ts-mode--test-this-expression) - '((this_expression) @font-lock-keyword-face) - '("this" @font-lock-keyword-face)) - - ;; avoid fontifying indentifiers with a keyword-values as identifiers. - ((identifier) @font-lock-keyword-face - (:match ,(concat "\\`" (regexp-opt csharp-ts-mode--keywords t) "\\'") @font-lock-keyword-face))) - - :language 'c-sharp - :override t - :feature 'attribute - `((attribute_list - "[" @csharp-ts-mode-attribute-face - (attribute name: (identifier) @csharp-ts-mode-attribute-face) - "]" @csharp-ts-mode-attribute-face)) - - :language 'c-sharp - :override t - :feature 'escape-sequence - '((escape_sequence) @font-lock-escape-face) - - :language 'c-sharp - :override t - :feature 'literal - `((integer_literal) @font-lock-number-face - (real_literal) @font-lock-number-face - (null_literal) @font-lock-constant-face - (boolean_literal) @font-lock-constant-face) - - :language 'c-sharp - :feature 'string - `([(string_literal) - (verbatim_string_literal) - ,@ (when (csharp-ts-mode--test-string-content) - '((string_content) - "\"")) - ,@(if (csharp-ts-mode--test-interpolated-string-text) - '((interpolated_string_text) - (interpolated_verbatim_string_text) - (character_literal) - "\"" - "$\"" - "@$\"" - "$@\"") - '((interpolation_start) - (interpolation_quote)))] - @font-lock-string-face) - - :language 'c-sharp - :feature 'type - `((predefined_type) @font-lock-type-face - (implicit_type) @font-lock-type-face - (nullable_type) @font-lock-type-face - (type_parameter - (identifier) @font-lock-type-face) - (type_argument_list - (identifier) @font-lock-type-face) - (type_argument_list - (generic_name - (identifier) @font-lock-type-face)) - (base_list - (generic_name - (identifier) @font-lock-type-face)) - (array_type - (identifier) @font-lock-type-face) - (qualified_name - name: (generic_name (identifier) @font-lock-type-face)) - (cast_expression (identifier) @font-lock-type-face) - (cast_expression (generic_name (identifier) @font-lock-type-face)) - ["operator"] @font-lock-type-face - (type_parameter_constraints_clause - (identifier) @font-lock-type-face) - ,@(if (csharp-ts-mode--test-type-constraint) - '((type_constraint type: (identifier) @font-lock-type-face) - (type_constraint type: (generic_name (identifier) @font-lock-type-face))) - '((type_parameter_constraint (type type: (identifier) @font-lock-type-face)) - (type_parameter_constraint (type type: (generic_name (identifier) @font-lock-type-face))))) - - ,@(when (csharp-ts-mode--test-type-of-expression) - '((type_of_expression (identifier) @font-lock-type-face))) - - ,@(when (csharp-ts-mode--test-typeof-expression) - '((typeof_expression (identifier) @font-lock-type-face))) - - (object_creation_expression - type: (identifier) @font-lock-type-face) - (object_creation_expression - type: (generic_name (identifier) @font-lock-type-face)) - (as_expression right: (identifier) @font-lock-type-face) - (as_expression right: (generic_name (identifier) @font-lock-type-face))) - - :language 'c-sharp - :feature 'definition - `((qualified_name (identifier) @font-lock-type-face) - (using_directive (identifier) @font-lock-type-face) - ,@(when (csharp-ts-mode--test-name-equals) - '((using_directive (name_equals - (identifier) @font-lock-type-face)))) - - (enum_declaration (identifier) @font-lock-type-face) - (enum_member_declaration (identifier) @font-lock-variable-name-face) - (field_declaration (variable_declaration (variable_declarator - name: (identifier) @font-lock-variable-name-face))) - - (interface_declaration (identifier) @font-lock-type-face) - - (struct_declaration (identifier) @font-lock-type-face) - - (record_declaration (identifier) @font-lock-type-face) - (namespace_declaration (identifier) @font-lock-type-face) - (base_list (identifier) @font-lock-type-face) - (property_declaration - type: (nullable_type) @font-lock-type-face - name: (identifier) @font-lock-variable-name-face) - (property_declaration - type: (predefined_type) @font-lock-type-face - name: (identifier) @font-lock-variable-name-face) - (property_declaration - type: (identifier) @font-lock-type-face - name: (identifier) @font-lock-variable-name-face) - (class_declaration (identifier) @font-lock-type-face) - - (constructor_declaration name: (_) @font-lock-type-face) - ;; Handle different releases of tree-sitter-c-sharp. - ;; Check if keyword void_keyword is available, then return the correct rule." - ,@(condition-case nil - (progn (treesit-query-capture 'csharp '((void_keyword) @capture)) - `((method_declaration ,csharp-ts-mode--type-field [(identifier) (void_keyword)] @font-lock-type-face))) - (error - `((method_declaration ,csharp-ts-mode--type-field [(identifier) (predefined_type)] @font-lock-type-face)))) - (method_declaration ,csharp-ts-mode--type-field (generic_name (identifier) @font-lock-type-face)) - (method_declaration name: (_) @font-lock-function-name-face) - - ;; only fontify known expression-types, to avoid the need to use :override - ;; for lambda-expressions in 'function below. - (variable_declarator - name: (identifier) @font-lock-variable-name-face - [(object_creation_expression) - (integer_literal) - (string_literal) - (binary_expression) - (invocation_expression) - (await_expression) - (member_access_expression) - (conditional_expression)]) - - (catch_declaration - ((identifier) @font-lock-type-face)) - (catch_declaration - ((identifier) @font-lock-type-face - (identifier) @font-lock-variable-name-face)) - - (variable_declaration (identifier) @font-lock-type-face) - (variable_declaration (qualified_name - name: (generic_name (identifier) @font-lock-type-face))) - (variable_declaration (generic_name (identifier) @font-lock-type-face)) - - (parameter type: (identifier) @font-lock-type-face) - (parameter type: (generic_name (identifier) @font-lock-type-face)) - (parameter name: (identifier) @font-lock-variable-name-face) - - (lambda_expression (identifier) @font-lock-variable-name-face) - (lambda_expression - parameters: (implicit_parameter) @font-lock-variable-name-face) - - (declaration_expression type: (identifier) @font-lock-type-face) - (declaration_expression name: (identifier) @font-lock-variable-name-face)) - - :language 'c-sharp - :feature 'function - '((invocation_expression - function: (identifier) @font-lock-function-call-face) - ((invocation_expression - function: (member_access_expression - expression: (identifier) @font-lock-variable-use-face)) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - (argument (identifier) @font-lock-variable-use-face) - ((argument (member_access_expression - expression: (identifier) @font-lock-variable-use-face)) - (:match "^[a-z][A-Za-z0-9]+" @font-lock-variable-use-face)) - (argument (member_access_expression - name: (identifier) @font-lock-property-use-face)) - ;; only highlight as function if variable contains lambda expression - (variable_declarator - name: (identifier) @font-lock-function-name-face - (lambda_expression))) - - :language 'c-sharp - :feature 'directives - :override t - (if (csharp-ts-mode--test-if-directive) - '((if_directive - "if" @font-lock-preprocessor-face - (identifier) @font-lock-variable-use-face) - (elif_directive - "elif" @font-lock-preprocessor-face - (identifier) @font-lock-variable-use-face) - (else_directive) @font-lock-preprocessor-face - (endif_directive) @font-lock-preprocessor-face - (define_directive - "define" @font-lock-preprocessor-face - (identifier) @font-lock-variable-use-face) - (nullable_directive) @font-lock-preprocessor-face - (pragma_directive) @font-lock-preprocessor-face - (region_directive) @font-lock-preprocessor-face - (endregion_directive) @font-lock-preprocessor-face - (region_directive - (preproc_message) @font-lock-variable-use-face) - (endregion_directive - (preproc_message) @font-lock-variable-use-face)) - '((preproc_if - "#if" @font-lock-preprocessor-face - (identifier) @font-lock-variable-use-face) - (preproc_elif - "#elif" @font-lock-preprocessor-face - (identifier) @font-lock-variable-use-face) - (preproc_else) @font-lock-preprocessor-face - "#endif" @font-lock-preprocessor-face - (preproc_define - "#define" @font-lock-preprocessor-face - (preproc_arg) @font-lock-variable-use-face) - (preproc_nullable) @font-lock-preprocessor-face - (preproc_pragma) @font-lock-preprocessor-face - (preproc_region) @font-lock-preprocessor-face - (preproc_endregion) @font-lock-preprocessor-face - (preproc_region - (preproc_arg) @font-lock-variable-use-face) - (preproc_endregion - (preproc_arg) @font-lock-variable-use-face))))))) + :language 'c-sharp + :feature 'directives + :override t + (if (csharp-ts-mode--test-if-directive) + '((if_directive + "if" @font-lock-preprocessor-face + (identifier) @font-lock-variable-use-face) + (elif_directive + "elif" @font-lock-preprocessor-face + (identifier) @font-lock-variable-use-face) + (else_directive) @font-lock-preprocessor-face + (endif_directive) @font-lock-preprocessor-face + (define_directive + "define" @font-lock-preprocessor-face + (identifier) @font-lock-variable-use-face) + (nullable_directive) @font-lock-preprocessor-face + (pragma_directive) @font-lock-preprocessor-face + (region_directive) @font-lock-preprocessor-face + (endregion_directive) @font-lock-preprocessor-face + (region_directive + (preproc_message) @font-lock-variable-use-face) + (endregion_directive + (preproc_message) @font-lock-variable-use-face)) + '((preproc_if + "#if" @font-lock-preprocessor-face + (identifier) @font-lock-variable-use-face) + (preproc_elif + "#elif" @font-lock-preprocessor-face + (identifier) @font-lock-variable-use-face) + (preproc_else) @font-lock-preprocessor-face + "#endif" @font-lock-preprocessor-face + (preproc_define + "#define" @font-lock-preprocessor-face + (preproc_arg) @font-lock-variable-use-face) + (preproc_nullable) @font-lock-preprocessor-face + (preproc_pragma) @font-lock-preprocessor-face + (preproc_region) @font-lock-preprocessor-face + (preproc_endregion) @font-lock-preprocessor-face + (preproc_region + (preproc_arg) @font-lock-variable-use-face) + (preproc_endregion + (preproc_arg) @font-lock-variable-use-face))))) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 15304486a5b..8d37bb53988 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3513,72 +3513,64 @@ characters of the current line." node parent bol args) js-indent-level))) -(defvar js--treesit-indent-rules-cached nil - "Cached tree-sitter indent rules for `js-ts-mode'.") - (defun js--treesit-indent-rules () - "Return tree-sitter indent rules for `js-ts-mode'. + "Return tree-sitter indent rules for `js-ts-mode'." + `((javascript + ((parent-is "program") parent-bol 0) + ((node-is "}") standalone-parent 0) + ((node-is ")") parent-bol 0) + ((node-is "]") parent-bol 0) + ((node-is ">") parent-bol 0) + ((and (parent-is "comment") c-ts-common-looking-at-star) + c-ts-common-comment-start-after-first-star -1) + ((parent-is "comment") prev-adaptive-prefix 0) + ((n-p-gp "identifier" "ternary_expression" "parenthesized_expression") + parent 0) + ((parent-is "ternary_expression") parent-bol js-indent-level) + ((parent-is "sequence_expression") parent 0) + ((parent-is "member_expression") js--treesit-member-chained-expression-helper 0) + ((parent-is "named_imports") parent-bol js-indent-level) + ((parent-is "statement_block") standalone-parent js-indent-level) + ((parent-is "variable_declarator") parent 0) + ((parent-is "arguments") parent-bol js-indent-level) + ((parent-is "array") parent-bol js-indent-level) + ((parent-is "formal_parameters") parent-bol js-indent-level) + ((parent-is "template_string") no-indent) ; Don't indent the string contents. + ((parent-is "template_substitution") parent-bol js-indent-level) + ((parent-is "object_pattern") parent-bol js-indent-level) + ((parent-is "object") parent-bol js-indent-level) + ((parent-is "pair") parent-bol js-indent-level) + ((parent-is "arrow_function") js--treesit-arrow-function-helper 0) + ((parent-is "parenthesized_expression") parent-bol js-indent-level) + ((parent-is "binary_expression") parent-bol js-indent-level) + ((parent-is "assignment_expression") parent-bol js-indent-level) + ((parent-is "class_body") parent-bol js-indent-level) + ;; "{" on the newline, should stay here. + ((node-is "statement_block") parent-bol 0) + ((parent-is "switch_statement") parent-bol 0) + ((parent-is "switch_body") js--treesit-switch-body-helper 0) + ((parent-is ,(rx "switch_" (or "case" "default"))) parent-bol js-indent-level) + ((match "while" "do_statement") parent-bol 0) + ((match "else" "if_statement") parent-bol 0) + ((parent-is ,(rx (or (seq (or "if" "for" "for_in" "while" "do") "_statement") + "else_clause"))) + parent-bol js-indent-level) -Tree-sitter indent rules are evaluated the first time this function is -called. Subsequent calls return the first evaluated value." - (or js--treesit-indent-rules-cached - (setq js--treesit-indent-rules-cached - `((javascript - ((parent-is "program") parent-bol 0) - ((node-is "}") standalone-parent 0) - ((node-is ")") parent-bol 0) - ((node-is "]") parent-bol 0) - ((node-is ">") parent-bol 0) - ((and (parent-is "comment") c-ts-common-looking-at-star) - c-ts-common-comment-start-after-first-star -1) - ((parent-is "comment") prev-adaptive-prefix 0) - ((n-p-gp "identifier" "ternary_expression" "parenthesized_expression") - parent 0) - ((parent-is "ternary_expression") parent-bol js-indent-level) - ((parent-is "sequence_expression") parent 0) - ((parent-is "member_expression") js--treesit-member-chained-expression-helper 0) - ((parent-is "named_imports") parent-bol js-indent-level) - ((parent-is "statement_block") standalone-parent js-indent-level) - ((parent-is "variable_declarator") parent 0) - ((parent-is "arguments") parent-bol js-indent-level) - ((parent-is "array") parent-bol js-indent-level) - ((parent-is "formal_parameters") parent-bol js-indent-level) - ((parent-is "template_string") no-indent) ; Don't indent the string contents. - ((parent-is "template_substitution") parent-bol js-indent-level) - ((parent-is "object_pattern") parent-bol js-indent-level) - ((parent-is "object") parent-bol js-indent-level) - ((parent-is "pair") parent-bol js-indent-level) - ((parent-is "arrow_function") js--treesit-arrow-function-helper 0) - ((parent-is "parenthesized_expression") parent-bol js-indent-level) - ((parent-is "binary_expression") parent-bol js-indent-level) - ((parent-is "assignment_expression") parent-bol js-indent-level) - ((parent-is "class_body") parent-bol js-indent-level) - ;; "{" on the newline, should stay here. - ((node-is "statement_block") parent-bol 0) - ((parent-is "switch_statement") parent-bol 0) - ((parent-is "switch_body") js--treesit-switch-body-helper 0) - ((parent-is ,(rx "switch_" (or "case" "default"))) parent-bol js-indent-level) - ((match "while" "do_statement") parent-bol 0) - ((match "else" "if_statement") parent-bol 0) - ((parent-is ,(rx (or (seq (or "if" "for" "for_in" "while" "do") "_statement") - "else_clause"))) - parent-bol js-indent-level) - - ;; JSX - ,@(js-jsx--treesit-indent-compatibility-bb1f97b) - ((node-is "jsx_closing_element") parent 0) - ((match "jsx_element" "statement") parent js-indent-level) - ((parent-is "jsx_element") parent js-indent-level) - ((parent-is "jsx_text") parent-bol js-indent-level) - ((parent-is "jsx_opening_element") parent js-indent-level) - ((parent-is "jsx_expression") parent-bol js-indent-level) - ((match "/" "jsx_self_closing_element") parent 0) - ((parent-is "jsx_self_closing_element") parent js-indent-level) - ;; FIXME(Theo): This no-node catch-all should be removed. When is it needed? - (no-node parent-bol 0)) - (jsdoc - ((and (parent-is "document") c-ts-common-looking-at-star) - c-ts-common-comment-start-after-first-star -1)))))) + ;; JSX + ,@(js-jsx--treesit-indent-compatibility-bb1f97b) + ((node-is "jsx_closing_element") parent 0) + ((match "jsx_element" "statement") parent js-indent-level) + ((parent-is "jsx_element") parent js-indent-level) + ((parent-is "jsx_text") parent-bol js-indent-level) + ((parent-is "jsx_opening_element") parent js-indent-level) + ((parent-is "jsx_expression") parent-bol js-indent-level) + ((match "/" "jsx_self_closing_element") parent 0) + ((parent-is "jsx_self_closing_element") parent js-indent-level) + ;; FIXME(Theo): This no-node catch-all should be removed. When is it needed? + (no-node parent-bol 0)) + (jsdoc + ((and (parent-is "document") c-ts-common-looking-at-star) + c-ts-common-comment-start-after-first-star -1)))) (defvar js--treesit-keywords '("as" "async" "await" "break" "case" "catch" "class" "const" "continue" @@ -3595,162 +3587,154 @@ called. Subsequent calls return the first evaluated value." "&&" "||" "!") "JavaScript operators for tree-sitter font-locking.") -(defvar js--treesit-font-lock-settings-cached nil - "Cached tree-sitter font-lock settings for `js-ts-mode'.") - (defun js--treesit-font-lock-settings () - "Return tree-sitter font-lock settings for `js-ts-mode'. + "Return tree-sitter font-lock settings for `js-ts-mode'." + (treesit-font-lock-rules -Tree-sitter font-lock settings are evaluated the first time this -function is called. Subsequent calls return the first evaluated value." - (or js--treesit-font-lock-settings-cached - (setq js--treesit-font-lock-settings-cached - (treesit-font-lock-rules + :language 'javascript + :feature 'comment + '([(comment) (hash_bang_line)] @font-lock-comment-face) - :language 'javascript - :feature 'comment - '([(comment) (hash_bang_line)] @font-lock-comment-face) + :language 'javascript + :feature 'constant + '(((identifier) @font-lock-constant-face + (:match "\\`[A-Z_][0-9A-Z_]*\\'" @font-lock-constant-face)) - :language 'javascript - :feature 'constant - '(((identifier) @font-lock-constant-face - (:match "\\`[A-Z_][0-9A-Z_]*\\'" @font-lock-constant-face)) + [(true) (false) (null)] @font-lock-constant-face) - [(true) (false) (null)] @font-lock-constant-face) + :language 'javascript + :feature 'keyword + `([,@js--treesit-keywords] @font-lock-keyword-face + [(this) (super)] @font-lock-keyword-face) - :language 'javascript - :feature 'keyword - `([,@js--treesit-keywords] @font-lock-keyword-face - [(this) (super)] @font-lock-keyword-face) + :language 'javascript + :feature 'string + '((regex pattern: (regex_pattern)) @font-lock-regexp-face + (string) @font-lock-string-face) - :language 'javascript - :feature 'string - '((regex pattern: (regex_pattern)) @font-lock-regexp-face - (string) @font-lock-string-face) + :language 'javascript + :feature 'string-interpolation + :override t + '((template_string) @js--fontify-template-string + (template_substitution ["${" "}"] @font-lock-misc-punctuation-face)) - :language 'javascript - :feature 'string-interpolation - :override t - '((template_string) @js--fontify-template-string - (template_substitution ["${" "}"] @font-lock-misc-punctuation-face)) + :language 'javascript + :feature 'definition + `(,@(js--treesit-font-lock-compatibility-definition-feature) - :language 'javascript - :feature 'definition - `(,@(js--treesit-font-lock-compatibility-definition-feature) + (class + name: (identifier) @font-lock-type-face) - (class - name: (identifier) @font-lock-type-face) + (class_declaration + name: (identifier) @font-lock-type-face) - (class_declaration - name: (identifier) @font-lock-type-face) + (function_declaration + name: (identifier) @font-lock-function-name-face) - (function_declaration - name: (identifier) @font-lock-function-name-face) + (method_definition + name: (property_identifier) @font-lock-function-name-face) - (method_definition - name: (property_identifier) @font-lock-function-name-face) + (formal_parameters + [(identifier) @font-lock-variable-name-face + (array_pattern (identifier) @font-lock-variable-name-face) + (object_pattern (shorthand_property_identifier_pattern) @font-lock-variable-name-face)]) - (formal_parameters - [(identifier) @font-lock-variable-name-face - (array_pattern (identifier) @font-lock-variable-name-face) - (object_pattern (shorthand_property_identifier_pattern) @font-lock-variable-name-face)]) + (variable_declarator + name: (identifier) @font-lock-variable-name-face) - (variable_declarator - name: (identifier) @font-lock-variable-name-face) + (variable_declarator + name: [(array_pattern (identifier) @font-lock-variable-name-face) + (object_pattern + (shorthand_property_identifier_pattern) @font-lock-variable-name-face)]) - (variable_declarator - name: [(array_pattern (identifier) @font-lock-variable-name-face) - (object_pattern - (shorthand_property_identifier_pattern) @font-lock-variable-name-face)]) + ;; full module imports + (import_clause (identifier) @font-lock-variable-name-face) + ;; named imports with aliasing + (import_clause (named_imports (import_specifier + alias: (identifier) @font-lock-variable-name-face))) + ;; named imports without aliasing + (import_clause (named_imports (import_specifier + !alias + name: (identifier) @font-lock-variable-name-face))) - ;; full module imports - (import_clause (identifier) @font-lock-variable-name-face) - ;; named imports with aliasing - (import_clause (named_imports (import_specifier - alias: (identifier) @font-lock-variable-name-face))) - ;; named imports without aliasing - (import_clause (named_imports (import_specifier - !alias - name: (identifier) @font-lock-variable-name-face))) + ;; full namespace import (* as alias) + (import_clause (namespace_import (identifier) @font-lock-variable-name-face))) - ;; full namespace import (* as alias) - (import_clause (namespace_import (identifier) @font-lock-variable-name-face))) + :language 'javascript + :feature 'assignment + '((assignment_expression + left: (_) @js--treesit-fontify-assignment-lhs)) - :language 'javascript - :feature 'assignment - '((assignment_expression - left: (_) @js--treesit-fontify-assignment-lhs)) + :language 'javascript + :feature 'function + '((call_expression + function: [(identifier) @font-lock-function-call-face + (member_expression + property: + (property_identifier) @font-lock-function-call-face)])) - :language 'javascript - :feature 'function - '((call_expression - function: [(identifier) @font-lock-function-call-face - (member_expression - property: - (property_identifier) @font-lock-function-call-face)])) + :language 'javascript + :feature 'jsx + '((jsx_opening_element name: (_) @font-lock-function-call-face) + (jsx_closing_element name: (_) @font-lock-function-call-face) + (jsx_self_closing_element name: (_) @font-lock-function-call-face) + (jsx_attribute (property_identifier) @font-lock-constant-face)) - :language 'javascript - :feature 'jsx - '((jsx_opening_element name: (_) @font-lock-function-call-face) - (jsx_closing_element name: (_) @font-lock-function-call-face) - (jsx_self_closing_element name: (_) @font-lock-function-call-face) - (jsx_attribute (property_identifier) @font-lock-constant-face)) + :language 'javascript + :feature 'property + '(((property_identifier) @font-lock-property-use-face) + (pair value: (identifier) @font-lock-variable-use-face) + ((shorthand_property_identifier) @font-lock-property-use-face)) - :language 'javascript - :feature 'property - '(((property_identifier) @font-lock-property-use-face) - (pair value: (identifier) @font-lock-variable-use-face) - ((shorthand_property_identifier) @font-lock-property-use-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 '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 '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 'bracket - '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face) + :language 'javascript + :feature 'delimiter + '((["," "." ";" ":"]) @font-lock-delimiter-face) - :language 'javascript - :feature 'delimiter - '((["," "." ";" ":"]) @font-lock-delimiter-face) + :language 'javascript + :feature 'escape-sequence + :override t + '((escape_sequence) @font-lock-escape-face) - :language 'javascript - :feature 'escape-sequence - :override t - '((escape_sequence) @font-lock-escape-face) + ;; "document" should be first, to avoid overlap. + :language 'jsdoc + :override t + :feature 'document + '((document) @font-lock-doc-face) - ;; "document" should be first, to avoid overlap. - :language 'jsdoc - :override t - :feature 'document - '((document) @font-lock-doc-face) + :language 'jsdoc + :override t + :feature 'keyword + '((tag_name) @font-lock-doc-markup-face) - :language 'jsdoc - :override t - :feature 'keyword - '((tag_name) @font-lock-doc-markup-face) + :language 'jsdoc + :override t + :feature 'bracket + '((["{" "}"]) @font-lock-bracket-face) - :language 'jsdoc - :override t - :feature 'bracket - '((["{" "}"]) @font-lock-bracket-face) + :language 'jsdoc + :override t + :feature 'property + '((type) @font-lock-type-face) - :language 'jsdoc - :override t - :feature 'property - '((type) @font-lock-type-face) - - :language 'jsdoc - :override t - :feature 'definition - '((identifier) @font-lock-variable-name-face))))) + :language 'jsdoc + :override t + :feature 'definition + '((identifier) @font-lock-variable-name-face))) (defun js--fontify-template-string (node override start end &rest _) "Fontify template string but not substitution inside it. diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index ea06c3f9dc9..953c115e69e 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -955,244 +955,228 @@ characters of the current line." ("::" . ?∷)) "Value for `prettify-symbols-alist' in `php-ts-mode'.") -(defvar php-ts-mode--font-lock-settings-cached nil - "Cached tree-sitter font-lock settings for `php-ts-mode'.") - (defun php-ts-mode--font-lock-settings () - "Return tree-sitter font-lock settings for `php-ts-mode'. + "Return tree-sitter font-lock settings for `php-ts-mode'." + (treesit-font-lock-rules -Tree-sitter font-lock settings are evaluated the first time this -function is called. Subsequent calls return the first evaluated value." - (or php-ts-mode--font-lock-settings-cached - (setq php-ts-mode--font-lock-settings-cached - (treesit-font-lock-rules + :language 'php + :feature 'keyword + :override t + `([,@(php-ts-mode--keywords)] @font-lock-keyword-face + ,@(when (php-ts-mode--test-visibility-modifier-operation-p) + '((visibility_modifier (operation) @font-lock-builtin-face))) + (var_modifier) @font-lock-builtin-face) - :language 'php - :feature 'keyword - :override t - `([,@(php-ts-mode--keywords)] @font-lock-keyword-face - ,@(when (php-ts-mode--test-visibility-modifier-operation-p) - '((visibility_modifier (operation) @font-lock-builtin-face))) - (var_modifier) @font-lock-builtin-face) + :language 'php + :feature 'comment + :override t + '((comment) @font-lock-comment-face) - :language 'php - :feature 'comment - :override t - '((comment) @font-lock-comment-face) + :language 'php + :feature 'constant + `((boolean) @font-lock-constant-face + (null) @font-lock-constant-face + ;; predefined constant or built in constant (part of PHP core) + ((name) @font-lock-builtin-face + (:match ,(rx-to-string + `(: bos (or ,@php-ts-mode--predefined-constant) eos)) + @font-lock-builtin-face)) + ;; user defined constant + ((name) @font-lock-constant-face + (:match "\\`_*[A-Z][0-9A-Z_]+\\'" @font-lock-constant-face)) + (const_declaration + (const_element (name) @font-lock-constant-face)) + ;; declare directive + (declare_directive ["strict_types" "encoding" "ticks"] @font-lock-constant-face)) - :language 'php - :feature 'constant - `((boolean) @font-lock-constant-face - (null) @font-lock-constant-face - ;; predefined constant or built in constant (part of PHP core) - ((name) @font-lock-builtin-face - (:match ,(rx-to-string - `(: bos (or ,@php-ts-mode--predefined-constant) eos)) - @font-lock-builtin-face)) - ;; user defined constant - ((name) @font-lock-constant-face - (:match "\\`_*[A-Z][0-9A-Z_]+\\'" @font-lock-constant-face)) - (const_declaration - (const_element (name) @font-lock-constant-face)) - ;; declare directive - (declare_directive ["strict_types" "encoding" "ticks"] @font-lock-constant-face)) + :language 'php + :feature 'name + '((goto_statement (name) @font-lock-constant-face) + (named_label_statement (name) @font-lock-constant-face)) - :language 'php - :feature 'name - '((goto_statement (name) @font-lock-constant-face) - (named_label_statement (name) @font-lock-constant-face)) + :language 'php + :feature 'delimiter + `((["," ":" ";" "\\"]) @font-lock-delimiter-face) - :language 'php - :feature 'delimiter - `((["," ":" ";" "\\"]) @font-lock-delimiter-face) + :language 'php + :feature 'operator + `((error_suppression_expression "@" @font-lock-keyword-face) + [,@(php-ts-mode--operators)] @font-lock-operator-face) - :language 'php - :feature 'operator - `((error_suppression_expression "@" @font-lock-keyword-face) - [,@(php-ts-mode--operators)] @font-lock-operator-face) + :language 'php + :feature 'variable-name + :override t + '(((name) @font-lock-keyword-face (:equal "this" @font-lock-keyword-face)) + (variable_name (name) @font-lock-variable-name-face) + (relative_scope ["parent" "self" "static"] @font-lock-builtin-face) + (relative_scope) @font-lock-constant-face + (dynamic_variable_name (name) @font-lock-variable-name-face) + (member_access_expression + name: (_) @font-lock-variable-name-face) + (scoped_property_access_expression + scope: (name) @font-lock-constant-face) + (nullsafe_member_access_expression (name) @font-lock-variable-name-face) + (error_suppression_expression (name) @font-lock-property-name-face)) - :language 'php - :feature 'variable-name - :override t - '(((name) @font-lock-keyword-face (:equal "this" @font-lock-keyword-face)) - (variable_name (name) @font-lock-variable-name-face) - (relative_scope ["parent" "self" "static"] @font-lock-builtin-face) - (relative_scope) @font-lock-constant-face - (dynamic_variable_name (name) @font-lock-variable-name-face) - (member_access_expression - name: (_) @font-lock-variable-name-face) - (scoped_property_access_expression - scope: (name) @font-lock-constant-face) - (nullsafe_member_access_expression (name) @font-lock-variable-name-face) - (error_suppression_expression (name) @font-lock-property-name-face)) + :language 'php + :feature 'string + `(("\"") @font-lock-string-face + (encapsed_string) @font-lock-string-face + (string_content) @font-lock-string-face + (string) @font-lock-string-face) - :language 'php - :feature 'string - `(("\"") @font-lock-string-face - (encapsed_string) @font-lock-string-face - (string_content) @font-lock-string-face - (string) @font-lock-string-face) + :language 'php + :feature 'literal + '((integer) @font-lock-number-face + (float) @font-lock-number-face + (heredoc identifier: (heredoc_start) @font-lock-constant-face) + (heredoc_body (string_content) @font-lock-string-face) + (heredoc end_tag: (heredoc_end) @font-lock-constant-face) + (nowdoc identifier: (heredoc_start) @font-lock-constant-face) + (nowdoc_body (nowdoc_string) @font-lock-string-face) + (nowdoc end_tag: (heredoc_end) @font-lock-constant-face) + (shell_command_expression) @font-lock-string-face) - :language 'php - :feature 'literal - '((integer) @font-lock-number-face - (float) @font-lock-number-face - (heredoc identifier: (heredoc_start) @font-lock-constant-face) - (heredoc_body (string_content) @font-lock-string-face) - (heredoc end_tag: (heredoc_end) @font-lock-constant-face) - (nowdoc identifier: (heredoc_start) @font-lock-constant-face) - (nowdoc_body (nowdoc_string) @font-lock-string-face) - (nowdoc end_tag: (heredoc_end) @font-lock-constant-face) - (shell_command_expression) @font-lock-string-face) + :language 'php + :feature 'type + :override t + '((union_type "|" @font-lock-operator-face) + (union_type) @font-lock-type-face + (bottom_type) @font-lock-type-face + (primitive_type) @font-lock-type-face + ((primitive_type) @font-lock-keyword-face + (:equal "callable" @font-lock-keyword-face)) + (cast_type) @font-lock-type-face + (named_type) @font-lock-type-face + (optional_type) @font-lock-type-face) - :language 'php - :feature 'type - :override t - '((union_type "|" @font-lock-operator-face) - (union_type) @font-lock-type-face - (bottom_type) @font-lock-type-face - (primitive_type) @font-lock-type-face - ((primitive_type) @font-lock-keyword-face - (:equal "callable" @font-lock-keyword-face)) - (cast_type) @font-lock-type-face - (named_type) @font-lock-type-face - (optional_type) @font-lock-type-face) + :language 'php + :feature 'definition + :override t + `((php_tag) @font-lock-preprocessor-face + ,@(if (php-ts-mode--test-php-end-tag-p) + '((php_end_tag) @font-lock-preprocessor-face) + '(("?>") @font-lock-preprocessor-face)) + ;; Highlights identifiers in declarations. + (class_declaration + name: (_) @font-lock-type-face) + (class_interface_clause (name) @font-lock-type-face) + (interface_declaration + name: (_) @font-lock-type-face) + (trait_declaration + name: (_) @font-lock-type-face) + (enum_declaration + name: (_) @font-lock-type-face) + (function_definition + name: (_) @font-lock-function-name-face) + ,@(when (php-ts-mode--test-property-hook-p) + '((property_hook (name) @font-lock-function-name-face))) + (method_declaration + name: (_) @font-lock-function-name-face) + (method_declaration + name: (name) @font-lock-builtin-face + (:match ,(rx-to-string + `(: bos (or ,@php-ts-mode--class-magic-methods) eos)) + @font-lock-builtin-face)) + ("=>") @font-lock-keyword-face + (object_creation_expression + (name) @font-lock-type-face) + ,@(when (php-ts-mode--test-namespace-name-as-prefix-p) + '((namespace_name_as_prefix "\\" @font-lock-delimiter-face) + (namespace_name_as_prefix + (namespace_name (name)) @font-lock-type-face))) + ,@(if (php-ts-mode--test-namespace-aliasing-clause-p) + '((namespace_aliasing_clause (name) @font-lock-type-face)) + '((namespace_use_clause alias: (name) @font-lock-type-face))) + ,@(when (not (php-ts-mode--test-namespace-use-group-clause-p)) + '((namespace_use_group + (namespace_use_clause (name) @font-lock-type-face)))) + (namespace_use_clause (name) @font-lock-type-face) + (namespace_name "\\" @font-lock-delimiter-face) + (namespace_name (name) @font-lock-type-face) + (use_declaration (name) @font-lock-property-use-face) + (use_instead_of_clause (name) @font-lock-type-face) + (binary_expression + operator: "instanceof" + right: (name) @font-lock-type-face)) - :language 'php - :feature 'definition - :override t - `((php_tag) @font-lock-preprocessor-face - ,@(if (php-ts-mode--test-php-end-tag-p) - '((php_end_tag) @font-lock-preprocessor-face) - '(("?>") @font-lock-preprocessor-face)) - ;; Highlights identifiers in declarations. - (class_declaration - name: (_) @font-lock-type-face) - (class_interface_clause (name) @font-lock-type-face) - (interface_declaration - name: (_) @font-lock-type-face) - (trait_declaration - name: (_) @font-lock-type-face) - (enum_declaration - name: (_) @font-lock-type-face) - (function_definition - name: (_) @font-lock-function-name-face) - ,@(when (php-ts-mode--test-property-hook-p) - '((property_hook (name) @font-lock-function-name-face))) - (method_declaration - name: (_) @font-lock-function-name-face) - (method_declaration - name: (name) @font-lock-builtin-face - (:match ,(rx-to-string - `(: bos (or ,@php-ts-mode--class-magic-methods) eos)) - @font-lock-builtin-face)) - ("=>") @font-lock-keyword-face - (object_creation_expression - (name) @font-lock-type-face) - ,@(when (php-ts-mode--test-namespace-name-as-prefix-p) - '((namespace_name_as_prefix "\\" @font-lock-delimiter-face) - (namespace_name_as_prefix - (namespace_name (name)) @font-lock-type-face))) - ,@(if (php-ts-mode--test-namespace-aliasing-clause-p) - '((namespace_aliasing_clause (name) @font-lock-type-face)) - '((namespace_use_clause alias: (name) @font-lock-type-face))) - ,@(when (not (php-ts-mode--test-namespace-use-group-clause-p)) - '((namespace_use_group - (namespace_use_clause (name) @font-lock-type-face)))) - (namespace_use_clause (name) @font-lock-type-face) - (namespace_name "\\" @font-lock-delimiter-face) - (namespace_name (name) @font-lock-type-face) - (use_declaration (name) @font-lock-property-use-face) - (use_instead_of_clause (name) @font-lock-type-face) - (binary_expression - operator: "instanceof" - right: (name) @font-lock-type-face)) + :language 'php + :feature 'function-scope + :override t + '((scoped_call_expression + scope: (name) @font-lock-constant-face) + (class_constant_access_expression (name) @font-lock-constant-face)) - :language 'php - :feature 'function-scope - :override t - '((scoped_call_expression - scope: (name) @font-lock-constant-face) - (class_constant_access_expression (name) @font-lock-constant-face)) + :language 'php + :feature 'function-call + :override t + '((function_call_expression + function: (name) @font-lock-function-call-face) + (scoped_call_expression + name: (name) @font-lock-function-call-face) + (member_call_expression + name: (name) @font-lock-function-call-face) + (nullsafe_member_call_expression + name: (_) @font-lock-function-call-face)) - :language 'php - :feature 'function-call - :override t - '((function_call_expression - function: (name) @font-lock-function-call-face) - (scoped_call_expression - name: (name) @font-lock-function-call-face) - (member_call_expression - name: (name) @font-lock-function-call-face) - (nullsafe_member_call_expression - name: (_) @font-lock-function-call-face)) + :language 'php + :feature 'argument + '((argument + name: (_) @font-lock-constant-face)) - :language 'php - :feature 'argument - '((argument - name: (_) @font-lock-constant-face)) + :language 'php + :feature 'escape-sequence + :override t + '((string (escape_sequence) @font-lock-escape-face) + (encapsed_string (escape_sequence) @font-lock-escape-face) + (heredoc_body (escape_sequence) @font-lock-escape-face)) - :language 'php - :feature 'escape-sequence - :override t - '((string (escape_sequence) @font-lock-escape-face) - (encapsed_string (escape_sequence) @font-lock-escape-face) - (heredoc_body (escape_sequence) @font-lock-escape-face)) + :language 'php + :feature 'base-clause + :override t + `((base_clause (name) @font-lock-type-face) + (use_as_clause (name) @font-lock-property-use-face) + ,@(when (not (php-ts-mode--test-namespace-name-as-prefix-p)) + '((qualified_name prefix: "\\" @font-lock-delimiter-face))) + (qualified_name (name) @font-lock-constant-face) + ,@(when (php-ts-mode--test-relative-name-p) + '((relative_name (name) @font-lock-constant-face)))) - :language 'php - :feature 'base-clause - :override t - `((base_clause (name) @font-lock-type-face) - (use_as_clause (name) @font-lock-property-use-face) - ,@(when (not (php-ts-mode--test-namespace-name-as-prefix-p)) - '((qualified_name prefix: "\\" @font-lock-delimiter-face))) - (qualified_name (name) @font-lock-constant-face) - ,@(when (php-ts-mode--test-relative-name-p) - '((relative_name (name) @font-lock-constant-face)))) + :language 'php + :feature 'property + '((enum_case + name: (_) @font-lock-type-face)) - :language 'php - :feature 'property - '((enum_case - name: (_) @font-lock-type-face)) + :language 'php + :feature 'attribute + '((((attribute (_) @attribute_name) @font-lock-preprocessor-face) + (:equal "Deprecated" @attribute_name)) + (attribute_group (attribute (name) @font-lock-constant-face))) - :language 'php - :feature 'attribute - '((((attribute (_) @attribute_name) @font-lock-preprocessor-face) - (:equal "Deprecated" @attribute_name)) - (attribute_group (attribute (name) @font-lock-constant-face))) + :language 'php + :feature 'bracket + '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face) - :language 'php - :feature 'bracket - '((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face) - - :language 'php - :feature 'error - :override t - '((ERROR) @php-ts-mode--fontify-error))))) + :language 'php + :feature 'error + :override t + '((ERROR) @php-ts-mode--fontify-error))) ;;; Font-lock helpers -(defvar php-ts-mode--custom-html-font-lock-settings-cached nil - "Cached tree-sitter font-lock settings for HTML when embedded in PHP.") - (defun php-ts-mode--custom-html-font-lock-settings () "Tree-sitter Font-lock settings for HTML when embedded in PHP. -Like `mhtml-ts-mode--font-lock-settings' but adapted for `php-ts-mode'. - -Tree-sitter font-lock settings are evaluated the first time this -function is called. Subsequent calls return the first evaluated value." - (or php-ts-mode--custom-html-font-lock-settings-cached - (setq php-ts-mode--custom-html-font-lock-settings-cached - (treesit-replace-font-lock-feature-settings - (treesit-font-lock-rules - :language 'html - :override t - :feature 'comment - '((comment) @font-lock-comment-face - ;; handle shebang path and others type of comment - (document (text) @font-lock-comment-face))) - (mhtml-ts-mode--treesit-font-lock-settings))))) +Like `mhtml-ts-mode--font-lock-settings' but adapted for `php-ts-mode'." + (treesit-replace-font-lock-feature-settings + (treesit-font-lock-rules + :language 'html + :override t + :feature 'comment + '((comment) @font-lock-comment-face + ;; handle shebang path and others type of comment + (document (text) @font-lock-comment-face))) + (mhtml-ts-mode--treesit-font-lock-settings))) (defvar php-ts-mode--phpdoc-font-lock-settings (treesit-font-lock-rules diff --git a/lisp/textmodes/mhtml-ts-mode.el b/lisp/textmodes/mhtml-ts-mode.el index b97555de2fc..fe68f17a6da 100644 --- a/lisp/textmodes/mhtml-ts-mode.el +++ b/lisp/textmodes/mhtml-ts-mode.el @@ -259,28 +259,20 @@ NODE and PARENT are ignored." css--treesit-font-lock-feature-list)) "Settings for `treesit-font-lock-feature-list'.") -(defvar mhtml-ts-mode--treesit-font-lock-settings-cached nil - "Cached tree-sitter font-lock settings for `mhtml-ts-mode'.") - (defun mhtml-ts-mode--treesit-font-lock-settings () - "Return tree-sitter font-lock settings for `mhtml-ts-mode'. - -Tree-sitter font-lock settings are evaluated the first time this -function is called. Subsequent calls return the first evaluated value." - (or mhtml-ts-mode--treesit-font-lock-settings-cached - (setq mhtml-ts-mode--treesit-font-lock-settings-cached - (append html-ts-mode--font-lock-settings - (js--treesit-font-lock-settings) - ;; Let's replace a css rule with a new one that adds - ;; color to the css value. - (treesit-replace-font-lock-feature-settings - (treesit-font-lock-rules - :language 'css - :override t - :feature 'variable - '((plain_value) @mhtml-ts-mode--colorize-css-value - (color_value) @mhtml-ts-mode--colorize-css-value)) - css--treesit-settings))))) + "Return tree-sitter font-lock settings for `mhtml-ts-mode'." + (append html-ts-mode--font-lock-settings + (js--treesit-font-lock-settings) + ;; Let's replace a css rule with a new one that adds + ;; color to the css value. + (treesit-replace-font-lock-feature-settings + (treesit-font-lock-rules + :language 'css + :override t + :feature 'variable + '((plain_value) @mhtml-ts-mode--colorize-css-value + (color_value) @mhtml-ts-mode--colorize-css-value)) + css--treesit-settings))) (defvar mhtml-ts-mode--treesit-thing-settings ;; In addition to putting together the various definitions, we need to @@ -300,34 +292,26 @@ function is called. Subsequent calls return the first evaluated value." `((defun ,css--treesit-defun-type-regexp)))) "Settings for `treesit-thing-settings'.") -(defvar mhtml-ts-mode--treesit-indent-rules-cached nil - "Cached tree-sitter indent rules for `mhtml-ts-mode'.") - (defun mhtml-ts-mode--treesit-indent-rules () - "Return tree-sitter indent rules for `mhtml-ts-mode'. - -Tree-sitter indent rules are evaluated the first time this function -is called. Subsequent calls return the first evaluated value." - (or mhtml-ts-mode--treesit-indent-rules-cached - (setq mhtml-ts-mode--treesit-indent-rules-cached - (treesit--indent-rules-optimize - (append html-ts-mode--indent-rules - ;; Extended rules for js and css, to indent - ;; appropriately when injected into html - (treesit-simple-indent-modify-rules - 'javascript - `((javascript ((parent-is "program") - mhtml-ts-mode--js-css-tag-bol - mhtml-ts-mode--js-css-indent-offset))) - (js--treesit-indent-rules) - :replace) - (treesit-simple-indent-modify-rules - 'css - `((css ((parent-is "stylesheet") - mhtml-ts-mode--js-css-tag-bol - mhtml-ts-mode--js-css-indent-offset))) - css--treesit-indent-rules - :prepend)))))) + "Return tree-sitter indent rules for `mhtml-ts-mode'." + (treesit--indent-rules-optimize + (append html-ts-mode--indent-rules + ;; Extended rules for js and css, to indent + ;; appropriately when injected into html + (treesit-simple-indent-modify-rules + 'javascript + `((javascript ((parent-is "program") + mhtml-ts-mode--js-css-tag-bol + mhtml-ts-mode--js-css-indent-offset))) + (js--treesit-indent-rules) + :replace) + (treesit-simple-indent-modify-rules + 'css + `((css ((parent-is "stylesheet") + mhtml-ts-mode--js-css-tag-bol + mhtml-ts-mode--js-css-indent-offset))) + css--treesit-indent-rules + :prepend)))) (defvar mhtml-ts-mode--treesit-aggregated-simple-imenu-settings `((html ,@html-ts-mode--treesit-simple-imenu-settings)